The Sweep AI IntelliJ extension (version 1.20.5) is a sophisticated AI-powered coding assistant that integrates Anthropic's Claude 3.5 Sonnet model with a comprehensive tool ecosystem for IntelliJ-based IDEs. This analysis is based on complete decompilation of the extension's JAR files (45 Java source files generated from Kotlin bytecode), revealing every system prompt, tool implementation, API configuration, and integration detail.
Key Discovery: The extension uses a detailed system prompt that emphasizes minimal code changes and proper file editing format, combined with 10 sophisticated built-in tools that provide comprehensive IDE integration through function calling.
- Architecture Overview
- Core System Prompt and AI Configuration
- Tool System Architecture
- AI Communication Architecture
- Platform-Specific Implementation
- Security and Safety Measures
- User Experience and UI Integration
- Performance Optimizations
- Technical Implementation Details
graph TD
A[IntelliJ IDE] --> B[Sweep Plugin Core v1.20.5]
B --> C[Chat Interface]
B --> D[Autocomplete Engine]
B --> E[Tool System]
B --> F[MCP Integration]
C --> G[Anthropic Claude 3.5 Sonnet]
D --> G
E --> H[Built-in Tools - 10 Types]
E --> I[External MCP Servers]
H --> J[BashTool]
H --> K[ReadFileTool]
H --> L[SearchFilesTool]
H --> M[StringReplaceTool]
H --> N[CreateFileTool]
H --> O[ListFilesTool]
H --> P[FindUsagesTool]
H --> Q[GetErrorsTool]
F --> R[MCP Server Management]
F --> S[Tool Discovery]
B --> T[Platform Layer]
T --> U[Windows/Linux - Ctrl]
T --> V[macOS - Cmd]
T --> W[Native Libraries]
Main Extension: jetbrains-1.20.5.jar
(2.98MB)
- Plugin ID:
dev.sweep.assistant.cloud
- Compatibility: IntelliJ IDEA 2024.1-2025.1
- Architecture: 1,012 compiled Kotlin classes in
dev.sweep.assistant.*
package - Dependencies: 62 external libraries including Anthropic Java SDK
The decompiled AssistantInstructions.class
reveals the complete, exact system prompt used by Sweep AI:
Source: AssistantInstructions.java
# Overview
You are Sweep, a programming assistant helping an engineer in their IDE.
## Code Editing Format
When suggesting edits, highlight the necessary modifications in your code blocks.
Use comments like `# ... existing code ...` or `// ... existing code ...` to indicate unchanged sections when making the edit.
Use the code editing format structure to suggest edits and create new files:
```language full_file_path
// ... existing code ...
[ edit_1 ]
// ... existing code ...
[ edit_2 ]
// ... existing code ...
Multiple files can be edited:
// ... existing code ...
[ edit_1 ]
// ... existing code ...
- Use actual file paths instead of placeholder paths in responses
- Show only the updates to the code since users can see the entire file
- Only rewrite entire files when specifically requested
- Language identifiers before paths are required
- Mark unchanged code regions with comments based on the language (example:
# ... existing code ...
for Python, Ruby and// ... existing code ...
for Java, TypeScript) - Preserve all existing code and comments in unmodified sections
The user has requested you follow these rules when completing their request:
- Keep explanations concise
- Use markdown formatting for all code blocks and terminal commands
- Follow the code editing format for file modifications and creation
- For new file creation implement the code in full and do not use placeholder comments
- For code edits:
- Use
// ... existing code ...
comments - Don't show unnecessary context as the user can see the entire file
- Use
- Make the minimal code changes necessary to solve the problem
- Terminal commands should be provided in markdown blocks
- Always work with the current relevant_files shown by the user
#### Secondary System Prompt
**Source**: [`AnthropicClient.java`](file:///Users/ghuntley/Downloads/sweepai/lib/decompiled/src/dev/sweep/assistant/api/AnthropicClient.java#L512)
You are a helpful AI assistant for software development. You're helping with a repository named {repoName}. Provide clear, concise, and accurate responses to coding questions. When suggesting code changes, be specific and explain your reasoning.
#### Context Formatting Template
**Source**: [`AnthropicClient.java - formatSnippetsForContext()`](file:///Users/ghuntley/Downloads/sweepai/lib/decompiled/src/dev/sweep/assistant/api/AnthropicClient.java)
```xml
<relevant_file index="{index}">
<source>
{file_path}:{start_line}-{end_line}
</source>
<file_contents>
{content}
</file_contents>
</relevant_file>
Primary Model: Claude 3.5 Sonnet (claude-3-5-sonnet-20241022
)
Available Models (from SweepConstants.class
):
claude-3-7-sonnet-latest
claude-3-7-sonnet-20250219
claude-3-5-haiku-latest
claude-3-5-haiku-20241022
claude-3-5-sonnet-latest
claude-3-5-sonnet-20241022
(primary)claude-3-5-sonnet-20240620
claude-3-opus-latest
- Legacy models:
claude-2.1
,claude-2.0
Model Selection Logic:
- Automatic model selection based on task complexity
- Fallback mechanisms for rate limits and errors
- "Thinking" mode support for complex reasoning tasks
Anthropic API Settings:
- Endpoint:
https://api.anthropic.com/v1/messages
- API Version:
2023-06-01
- Authentication: Header-based API key (
x-api-key
) - Content Type:
application/json
- Streaming: Server-Sent Events (SSE) for real-time responses
Source: ToolType.java
The system uses an enum-based registry:
READ_FILE = new ToolType("read_file", ReadFileTool.class);
CREATE_FILE = new ToolType("create_file", CreateFileTool.class);
STR_REPLACE = new ToolType("str_replace", StringReplaceTool.class);
LIST_FILES = new ToolType("list_files", ListFilesTool.class);
SEARCH_FILES = new ToolType("search_files", SearchFilesTool.class);
FIND_USAGES = new ToolType("find_usages", FindUsagesTool.class);
GET_ERRORS = new ToolType("get_errors", GetErrorsTool.class);
BASH = new ToolType("bash", BashTool.class);
PROMPT_CRUNCHING = new ToolType("prompt_crunching", PromptCrunchingTool.class);
UPDATE_ACTION_PLAN = new ToolType("update_action_plan", UpdateActionPlanTool.class);
ToolCall (ToolCall.java
):
@Serializable
public final class ToolCall {
@JsonProperty("tool_call_id") String toolCallId;
@JsonProperty("tool_name") String toolName;
@JsonProperty("tool_parameters") Map<String, String> toolParameters;
@JsonProperty("raw_text") String rawText;
@JsonProperty("is_mcp") boolean isMcp;
@JsonProperty("mcp_properties") Map<String, String> mcpProperties;
}
CompletedToolCall (CompletedToolCall.java
):
@Serializable
public final class CompletedToolCall {
@JsonProperty("tool_call_id") String toolCallId;
@JsonProperty("tool_name") String toolName;
@JsonProperty("result_string") String resultString;
@JsonProperty("status") boolean status; // true = success, false = error
@JsonProperty("is_mcp") boolean isMcp;
@JsonProperty("mcp_properties") Map<String, String> mcpProperties;
}
The extension provides 10 sophisticated built-in tools. Here's the complete implementation analysis for each:
Source: BashTool.java
Complete Implementation Flow:
- Parameter Validation: Extracts
command
,timeout
(default 300s, max 1800s),explanation
- Security Checks:
- Validates against banned commands:
curl
,wget
,chrome
,firefox
, etc. - Checks Claude permission settings from
~/.config/claude/settings.json
- Requires user confirmation unless auto-approved
- Validates against banned commands:
- Terminal Management: Creates/reuses "Sweep Terminal" in IntelliJ
- Command Execution: Appends unique marker
__SWEEP_TERMINAL_COMMAND_FINISHED_<timestamp>_<random>
- Output Processing: Extracts output between initial state and finish marker
Exact Error Messages:
// Security denials
"Error: Command '" + command + "' is denied by Claude settings. This " + toolDisplayName + " command is not allowed. If you cannot accomplish your task without this command, please let me know and provide alternative methods to achieve the same result."
// Banned commands
"Error: Command contains the banned command '" + bannedCommand + "'. This " + toolDisplayName + " command is not allowed. If you cannot accomplish your task without this command, please let me know and provide alternative methods to achieve the same result."
// User rejection
"Rejected: I have rejected the " + toolDisplayName + " command: " + command
// System errors
"Error: Project base path is not available. Cannot execute " + toolDisplayName + " command without a valid working directory. Try calling " + toolDisplayName + " one more time but if this persists let me know that you are unable to use the " + toolDisplayName + " tool right now and to contact the Sweep Team."
Security Implementation:
// Banned command checking
private final String checkForBannedCommands(String command) {
List commandWords = new Regex("\\s+").split(command, 0);
for (String bannedCommand : BANNED_COMMANDS) {
if (commandWords.contains(bannedCommand)) {
return bannedCommand;
}
}
return null;
}
Source: ReadFileTool.java
Complete Implementation Flow:
- Parameter Extraction: Validates and processes file path parameter
- Path Resolution: Handles both absolute and relative paths using project base path
- Dual Access Strategy: Uses VirtualFile system first, falls back to standard File I/O
- Size-Based Truncation: Automatic truncation for files > 200KB
- Smart Content Handling: UTF-8 encoding with fallback mechanisms
Exact Error Messages:
// Git LFS detection
"Error: Cannot read Git LFS file. This file is stored in Git Large File Storage and contains only a pointer."
// File not found
"Error: File not found at path: " + filePath
// General read errors
"Error reading file: " + e.getMessage()
Smart Truncation Implementation:
// Constants from decompiled source
private static final int TRUNCATION_LINES = 5;
private static final int TRUNCATION_CHARS = 4000;
private static final String TRUNCATION_MESSAGE = "\n\n... [truncated due to extremely large size of file]";
// Truncation logic
return lines.size() <= 5 && content.length() <= 4000 ? content :
(truncatedContent.length() > 4000 ?
StringsKt.take(truncatedContent, 4000) + TRUNCATION_MESSAGE :
truncatedContent + TRUNCATION_MESSAGE);
Path Resolution Logic:
// Absolute path resolution from decompiled source
if (!new File(filePath).isAbsolute() && projectBasePath != null) {
String[] stringArray = new String[]{filePath};
absolutePath = Paths.get(projectBasePath, stringArray).toString();
} else {
absolutePath = filePath;
}
Source: CreateFileTool.java
Complete Implementation Flow:
- Parameter Validation: Validates path and content parameters
- Directory Creation: Automatically creates parent directories if needed
- File Existence Check: Detects existing files for modification preview
- Visual Diff Dialog: Shows side-by-side comparison for user approval
- VCS Integration: Automatic git add after file creation
- Context Update: Updates conversation history with file metadata
Exact Error Messages:
// Parameter validation
"Error: File path parameter is required"
// Processing errors
"Error writing file: " + e.getMessage()
// User rejection
"Rejected: I have rejected the file creation for: " + filePath
Dialog Implementation Details:
// File preview dialog setup
FilePreviewDialog dialog = new FilePreviewDialog(project, filePath, existingContent, newContent, fileExists);
dialog.setTitle(fileExists ? "Preview File Modification - " + filePath : "Preview File Creation - " + filePath);
dialog.setModal(true);
// Keyboard shortcuts from decompiled source
if (e.getKeyCode() == 10 && !e.isMetaDown()) {
this.close(0); // Accept with Enter
} else if (e.getKeyCode() == 10 && e.isMetaDown()) {
SweepConfig.getInstance(project).addAutoApprovedTools(SetsKt.setOf("create_file"));
this.close(0); // Auto-accept with Cmd/Ctrl+Enter
} else if (e.getKeyCode() == 8) {
this.close(1); // Reject with Backspace
}
Success Message Format:
// Content analysis for success message
String contextInfo = !lines.isEmpty() ?
"Here's what the beginning of the file looks like:\n```\n" +
CollectionsKt.joinToString(previewLines, "\n", null, null, 0, null, CreateFileTool::lambda$8, 30, null) +
(lines.size() > 5 ? "\n ..." : "") +
"\n```\n\n\nRemember to use the get_errors tool at the very end after you are finished modifying everything to check for any issues." : "";
return "Successfully wrote " + content.length() + " characters (" + fileSize + " bytes) to file: " + filePath + ". " + contextInfo;
Source: StringReplaceTool.java
Complete Implementation Flow:
- Parameter Validation: Validates path, old_str, and new_str parameters
- Dual Mode Operation: Supports both preview mode and direct application
- Occurrence Validation: Ensures exactly one occurrence of old_str
- Document vs File Access: Uses IntelliJ Document API when available
- Context Extraction: Provides surrounding code context in results
- Change Tracking: Updates conversation history with modification metadata
Exact Error Messages:
// Parameter validation errors
"Error: File path parameter is required"
"Error: old_str parameter is required and cannot be empty"
"Error: old_str and new_str are identical. No replacement made. Double check that the changes have not already been made."
// File access errors
"Error: File not found at path: " + filePath
"Error: Path does not point to a file: " + filePath
// Content validation errors
"Error: String to replace not found in file: '" + oldStr + "'"
"Error: String '" + oldStr + "' occurs " + occurrences + " times in the file. Expected exactly 1 occurrence for safe replacement."
// Processing errors
"Error performing string replacement: " + e.getMessage()
Occurrence Detection Logic:
// From decompiled source - exact occurrence counting
String[] stringArray = new String[]{normalizedOldStr};
int occurrences = StringsKt.split$default(originalContent, stringArray, false, 0, 6, null).size() - 1;
if (occurrences != 1) {
return new CompletedToolCall(toolCallId, "str_replace",
"Error: String '" + oldStr + "' occurs " + occurrences + " times in the file. Expected exactly 1 occurrence for safe replacement.",
false, false, null, 48, null);
}
Context Analysis Implementation:
// Context extraction for successful replacements
if (startLineIndex != -1) {
int contextStart = Math.max(0, startLineIndex - 2);
int contextEnd = Math.min(lines.size() - 1, startLineIndex + newStrLines.size() + 1);
List contextLines = lines.subList(contextStart, contextEnd + 1);
return "Here is what that portion of the file now looks like with +/- 2 lines for context:\n<updated_code>\n" +
CollectionsKt.joinToString$default(contextLines, "\n", null, null, 0, null, StringReplaceTool::lambda$10, 30, null) +
"\n</updated_code>\n\n\nRemember to use the get_errors tool at the very end after you are finished modifying everything to check for any issues.";
}
Source: SearchFilesTool.java
Complete Implementation Flow:
- Regex Optimization: Automatically removes redundant
.*
patterns for performance - Dual Search Strategy: Concurrent content and filename searching with timeout protection
- IntelliJ Integration: Uses FindInProjectUtil for semantic-aware search
- Result Merging: Sophisticated overlap detection and line segment merging
- Gitignore Awareness: Respects VCS ignore patterns and file status
- Output Formatting: Structured results with context and truncation handling
Constants and Limits:
// From decompiled constants
public static final int MAX_RESULTS = 750;
public static final int MAX_RESULT_LENGTH = 165000;
public static final int MAX_FILENAME_RESULTS = 100;
public static final int MAX_FILENAME_RESULT_LENGTH = 25000;
public static final long SEARCH_TIMEOUT_MS = 5000L;
public static final long SEARCH_FILENAME_TIMEOUT_MS = 5000L;
Regex Optimization Logic:
// Smart regex optimization from decompiled source
private final String optimizeRegex(String regex) {
String optimized = regex;
if (StringsKt.startsWith$default(optimized, ".*", false, 2, null)) {
String withoutLeading = optimized.substring(2);
try {
Pattern.compile(withoutLeading, 2);
optimized = withoutLeading;
} catch (Exception exception) {}
}
if (StringsKt.endsWith$default(optimized, ".*", false, 2, null)) {
String withoutTrailing = optimized.substring(0, optimized.length() - 2);
try {
Pattern.compile(withoutTrailing, 2);
optimized = withoutTrailing;
} catch (Exception exception) {}
}
return optimized;
}
Timeout and Cancellation:
// Content search timeout handling
private static final boolean searchInFileContents$lambda$2(long startTime, SearchFilesTool this$0,
List hits, int maxResults, Project project, UsageInfo usage) {
long elapsed = System.currentTimeMillis() - startTime;
if (elapsed > 5000L) {
this$0.contentSearchTimedOut = true;
return false;
}
if (hits.size() >= maxResults) {
return false;
}
// Process usage...
return true;
}
Result Structure:
// Output format structure
"=== FILENAME MATCHES NOT ALREADY IN CONTENT RESULTS (" + uniqueFilenameHits.size() + ") ==="
"=== CONTENT MATCHES (" + contentHits.size() + ") ==="
"at lines " + snippet.getFirst() + ":"
"... (showing first " + maxResults + " content results)"
Source: ListFilesTool.java
Complete Implementation Flow:
- Project Structure Analysis: Uses ProjectFileIndex for content validation
- Recursive Tree Building: Builds hierarchical TreeNode structure with depth limits
- File Count Calculation: Pre-calculates descendant file counts for directories
- Intelligent Filtering: Excludes hidden files, gitignored content, and tmp directories
- Size-Based Truncation: Dynamic reduction when output exceeds limits
- Empty Directory Analysis: Provides detailed reasons for empty directories
Constants and Limits:
// From decompiled constants
private static final int DEFAULT_MAX_DEPTH = 10;
private static final int DEFAULT_MAX_FILES = 300;
Empty Directory Analysis:
// EmptyReason enum values from decompiled source
TRULY_EMPTY("No files or directories found in this directory.")
ALL_GITIGNORED("No files to display - files in this directory are gitignored.")
ALL_FILTERED("No files to display - files in this directory are filtered out (hidden files, outside project content, etc.).")
MIXED_FILTERED("No files to display - files in this directory are either gitignored or filtered out by other criteria.")
Dynamic Size Reduction:
// Size-based output optimization
int maxLength = 50000;
if (treeString.length() > maxLength) {
int reducedDepth = Math.max(2, maxDepth / 2);
int reducedFiles = Math.max(50, maxFiles / 2);
treeString = generateTree(startVirtualFile, projectBaseVf, projectFileIndex2, project, startPathArg, recursive, reducedDepth, reducedFiles);
treeString = treeString.length() > maxLength ?
StringsKt.take(treeString, maxLength) + "\n\n[Output truncated - result was too large. Please use a more specific path or set recursive=false for smaller output.]" :
treeString + "\n\n[Output was reduced (depth: " + reducedDepth + ", max files: " + reducedFiles + ") due to size. Use a more specific path for full detail.]";
}
Tree Rendering Format:
// Tree structure characters
"└ " : "├ " // Last vs non-last items
" " : "│ " // Children prefix fill
Source: FindUsagesTool.java
Complete Implementation Flow:
- Symbol Search: Uses PsiSearchHelper to find symbol occurrences across project
- Element Processing: Processes PsiNameIdentifierOwner elements for declarations
- Reference Resolution: Uses ReferencesSearch for finding all symbol usages
- Context Extraction: Provides line-level context for each usage
- File Grouping: Groups results by file with line number sorting
- Truncation Handling: Limits results to 500 with progress indication
Constants:
public static final int MAX_RESULTS = 500;
Symbol Processing Logic:
// Symbol identification from decompiled source
if (element instanceof PsiNameIdentifierOwner) {
PsiElement nameIdentifier = ((PsiNameIdentifierOwner)element).getNameIdentifier();
if (Intrinsics.areEqual(nameIdentifier != null ? nameIdentifier.getText() : null, searchName)) {
matchingElements.add(element);
// Find all references to this element
Collection references = ReferencesSearch.search(element, scope).findAll();
// Process each reference...
}
}
Context Extraction:
// Line context extraction with truncation
Document document = FileDocumentManager.getInstance().getDocument(containingFile.getVirtualFile());
int lineNumber = document.getLineNumber(startOffset);
int lineStartOffset = document.getLineStartOffset(lineNumber);
int lineEndOffset = document.getLineEndOffset(lineNumber);
String lineText = document.getText(new TextRange(lineStartOffset, lineEndOffset));
String truncatedLineText = lineText.trim().length() > 280 ?
StringsKt.take(lineText.trim(), 130) + "... [truncated due to length]" :
lineText.trim();
Output Format:
// Result formatting structure
"Found " + usages.size() + " usage(s) of \"" + searchName + "\":"
fileUsages.size() + " usage(s) in `" + relativePath + "`:"
"at line " + usage.getLineNumber() + ":"
"... (showing first 500 results)"
Source: GetErrorsTool.java
Complete Implementation Flow:
- File Type Validation: Skips markdown files automatically
- PSI Analysis: Uses PsiManager for semantic file analysis
- Problem Retrieval: Integrates with SweepProblemRetriever for comprehensive diagnostics
- Severity Filtering: Filters to ERROR-level and above (excluding warnings/info)
- Context Extraction: Provides problematic code snippets with exact locations
- Safe Offset Handling: Bounds checking for all text range operations
Exact Error Messages:
// File validation
"Error: File path parameter is required"
"Error: File not found at path: " + filePath
"Error: Could not analyze file: " + filePath
// Results
"No severe-level problems found in file: " + filePath
"No severe-level problems found in the file: " + filePath + " since it is a markdown file."
Problem Processing Logic:
// Severity filtering from decompiled source
List<HighlightInfo> allProblems = SweepProblemRetriever.INSTANCE.getProblemsDisplayedInProblemsView(project, psiFile, HighlightSeverity.INFORMATION);
List severeProblems = allProblems.stream()
.filter(problem -> problem.getSeverity().myVal >= HighlightSeverity.ERROR.myVal)
.collect(Collectors.toList());
Output Format Structure:
// Detailed problem reporting
"Found " + severeProblems.size() + " severe-level problem(s) in file: " + filePath
index + 1 + ". "
"Severity: " + problem.getSeverity().myName
" Location: Line " + getLineNumber(psiFile, problem.getActualStartOffset()) + ", "
"Characters " + problem.getActualStartOffset() + "-" + problem.getActualEndOffset()
" Description: " + problem.getDescription()
" Problematic text: \"" + problemText.trim() + "\""
Source: PromptCrunchingTool.java
Complete Implementation Flow:
- Summary Validation: Validates that summary parameter is provided and non-empty
- Simple Processing: Formats and returns the provided summary
- Error Handling: Returns detailed error for missing/empty summary
Exact Implementation:
// Complete tool implementation from decompiled source
public CompletedToolCall execute(ToolCall toolCall, Project project, String conversationId) {
String summary = toolCall.getToolParameters().get("summary");
return summary == null || StringsKt.isBlank(summary) ?
new CompletedToolCall(toolCallId, "prompt_crunching",
"Error: Summary parameter is required but was not provided or is empty.",
false, false, null, 48, null) :
new CompletedToolCall(toolCallId, "prompt_crunching",
"Summary of conversation:\n\n" + summary,
true, false, null, 48, null);
}
Source: UpdateActionPlanTool.java
Complete Implementation Flow:
- Parameter Extraction: Extracts action_plan from tool parameters
- Message Discovery: Finds the last assistant message in conversation
- Annotation Management: Creates or updates message annotations
- Database Persistence: Asynchronously saves changes to chat history
- Error Recovery: Handles missing messages gracefully with warnings
Message Processing Logic:
// Last assistant message discovery from decompiled source
List messageList = MessageList.Companion.getInstance(project);
ListIterator iterator = messageList.listIterator(messageList.size());
while (iterator.hasPrevious()) {
Message it = (Message)iterator.previous();
if (it.getRole() == MessageRole.ASSISTANT) {
lastAssistantMessage = it;
break;
}
}
Annotation Management:
// Annotation creation and update
if (lastAssistantMessage.getAnnotations() == null) {
int messageIndex = messageList.indexOf(lastAssistantMessage);
if (messageIndex != -1) {
Message updatedMessage = Message.copy$default(lastAssistantMessage, null, null,
new Annotations(null, null, null, null, null, null, 63, null),
null, null, null, null, null, 251, null);
messageList.set(messageIndex, updatedMessage);
}
}
// Set action plan in annotations
annotations.setActionPlan(actionPlan);
Error Handling:
// Missing message handling
if (lastAssistantMessage == null) {
logger.warn("No assistant message found to attach action plan to");
return new CompletedToolCall(toolCallId, "update_action_plan",
"Warning: No assistant message found to attach action plan to",
false, false, null, 48, null);
}
// McpTool.class - Universal MCP adapter
interface McpTool extends SweepTool {
// Parameter type conversion
when (parameterType) {
"string" -> value
"number" -> value.toDoubleOrNull() ?: value.toIntOrNull() ?: value
"boolean" -> value.toLowerCase() == "true"
"array" -> Json.parseToJsonElement(value).jsonArray
}
}
- SweepMcpService: Connection management and lifecycle
- SweepMcpClient: Individual server communication
- Dynamic Discovery: Automatic tool registration from servers
- Schema Validation: JSON schema-based parameter validation
Source: AnthropicClient.java
// Complete API configuration from decompiled source
private static final String ANTHROPIC_API_URL = "https://api.anthropic.com/v1/messages";
private static final String ANTHROPIC_MODEL = "claude-3-5-sonnet-20241022";
private static final String ANTHROPIC_VERSION = "2023-06-01";
// Connection setup
HttpURLConnection connection = new URL(ANTHROPIC_API_URL).openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("x-api-key", SweepSettings.getInstance().getAnthropicApiKey());
connection.setRequestProperty("anthropic-version", ANTHROPIC_VERSION);
connection.setDoOutput(true);
connection.setDoInput(true);
// Complete request body construction from decompiled source
Map requestBody = MapsKt.mapOf(new Pair[]{
TuplesKt.to("model", "claude-3-5-sonnet-20241022"),
TuplesKt.to("messages", anthropicMessages),
TuplesKt.to("system", systemPrompt),
TuplesKt.to("stream", Boxing.boxBoolean(true)),
TuplesKt.to("max_tokens", Boxing.boxInt(4096))
});
// Complete streaming response handling from decompiled source
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
Ref.ObjectRef line = new Ref.ObjectRef();
while (true) {
Object lineContent = reader.readLine();
line.element = lineContent;
if (lineContent != null && !isCancelled.get()) {
if (StringsKt.startsWith$default((String)lineContent, "data: ", false, 2, null)) {
String data = ((String)lineContent).substring(6);
if (!Intrinsics.areEqual(data, "[DONE]")) {
try {
JsonNode jsonNode = mapper.readTree(data);
String delta = jsonNode.path("delta").path("text").asText("");
if (delta.length() > 0) {
onChunk.invoke(delta);
}
} catch (Exception e) {
logger.warn("Failed to parse Anthropic response chunk", e);
}
}
}
} else {
break;
}
}
Source: AnthropicClient.java - streamMessages()
Complete Message Processing Flow:
- Message Preprocessing: Formats user messages with context and rules
- System Prompt Injection: Adds comprehensive system instructions
- File Context Integration: Embeds code snippets in structured format
- Rule Application: Applies user-specified behavioral rules
Context Formatting Implementation:
// Complete context formatting from decompiled source
private final String formatSnippetsForContext(List<Snippet> snippets) {
if (snippets.isEmpty()) {
return "";
}
StringBuilder formattedSnippets = new StringBuilder();
for (int index = 0; index < snippets.size(); index++) {
Snippet snippet = snippets.get(index);
String lineInfo = snippet.is_full_file() ? "" : ":" + snippet.getStart() + "-" + snippet.getEnd();
formattedSnippets.append("<relevant_file index=\"" + index + "\">\n");
formattedSnippets.append("<source>\n");
formattedSnippets.append(snippet.getFile_path() + lineInfo + "\n");
formattedSnippets.append("</source>\n");
formattedSnippets.append("<file_contents>\n");
formattedSnippets.append(snippet.getContent() + "\n");
formattedSnippets.append("</file_contents>\n");
formattedSnippets.append("</relevant_file>");
}
return formattedSnippets.toString();
}
Message Role Conversion:
// Complete role mapping from decompiled source
switch (message.getRole().ordinal()) {
case 1: // USER
return MapsKt.mapOf(new Pair[]{
TuplesKt.to("role", "user"),
TuplesKt.to("content", message.getContent())
});
case 2: // ASSISTANT
return MapsKt.mapOf(new Pair[]{
TuplesKt.to("role", "assistant"),
TuplesKt.to("content", message.getContent())
});
default:
return null;
}
System Prompt Construction:
// Complete system prompt assembly from decompiled source
String rulesPrompt = "";
if (currentRules.length() > 0) {
rulesPrompt = "### Additional Rules\nThe user has requested you follow these rules when completing their request:\n<rules>\n" +
currentRules + "\n</rules>";
}
// Full system prompt with context integration
String finalSystemPrompt = "# Overview\nYou are Sweep, a programming assistant helping an engineer in their IDE.\n\n" +
"## Code Editing Format\nWhen suggesting edits, highlight the necessary modifications in your code blocks.\n" +
"Use comments like `# ... existing code ...` or `// ... existing code ...` to indicate unchanged sections when making the edit.\n\n" +
// ... [complete system prompt text] ...
rulesPrompt + "\n" + lastUserMessageContent;
Repository Context Integration:
// Complete repository context from decompiled source
if (!messagesWithContext.isEmpty() && messagesWithContext.get(0).getRole() == MessageRole.USER) {
Message firstMessage = messagesWithContext.get(0);
String updatedContent = "# Codebase\nRepository Name: " + repoName +
"\nThe latest versions of the codebase files are provided below.\n\n" +
"<relevant_files>\n" + snippetsContext + "\n</relevant_files>\n\n" +
firstMessage.getContent();
messagesWithContext.set(0, Message.copy$default(firstMessage, MessageRole.USER, updatedContent,
null, null, null, null, null, null, 252, null));
}
// Complete cancellation mechanism from decompiled source
private final AtomicBoolean isCancelled = new AtomicBoolean(false);
public final void cancel() {
this.isCancelled.set(true);
}
// Error handling in streaming
try {
// API key validation
String apiKey = SweepSettings.getInstance().getAnthropicApiKey();
if (StringsKt.isBlank(apiKey)) {
throw new IllegalStateException("Anthropic API key is not set");
}
// Stream processing with cancellation checks
if (lineContent != null && !isCancelled.get()) {
// Process streaming data...
}
} finally {
connection.disconnect();
}
// Complete JSON mapper setup from decompiled source
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new KotlinModule.Builder()
.withReflectionCacheSize(512)
.build());
// Complete connection lifecycle from decompiled source
HttpURLConnection connection = null;
try {
connection = createConnection();
// Write request body
try (OutputStream os = connection.getOutputStream()) {
os.write(mapper.writeValueAsBytes(requestBody));
os.flush();
}
// Process streaming response
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
// ... streaming logic ...
} finally {
if (connection != null) {
connection.disconnect();
}
}
// Complete async execution from decompiled source
return BuildersKt.withContext(Dispatchers.getIO(), new Function2<CoroutineScope, Continuation<Unit>, Object>() {
public final Object invokeSuspend(Object result) {
switch (this.label) {
case 0:
ResultKt.throwOnFailure(result);
isCancelled.set(false);
// ... API execution logic ...
return Unit.INSTANCE;
}
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
});
<!-- plugin.xml configuration -->
<action id="newSweepAiChat" class="dev.sweep.assistant.actions.NewChatAction">
<keyboard-shortcut keymap="$default" first-keystroke="meta J"/> <!-- macOS -->
<keyboard-shortcut keymap="$default" first-keystroke="ctrl J"/> <!-- Windows/Linux -->
</action>
<action id="focusSweepChat" class="dev.sweep.assistant.actions.FocusChatAction">
<keyboard-shortcut keymap="$default" first-keystroke="meta shift J"/> <!-- macOS -->
<keyboard-shortcut keymap="$default" first-keystroke="ctrl shift J"/> <!-- Windows/Linux -->
</action>
Action | macOS | Windows/Linux | Function |
---|---|---|---|
New Chat | Cmd+J |
Ctrl+J |
Start new conversation |
Add to Chat | Cmd+Shift+J |
Ctrl+Shift+J |
Add selection to existing chat |
Prompt Bar | Cmd+I |
Ctrl+I |
Show inline prompt interface |
Apply Code | Cmd+Enter |
Ctrl+Enter |
Accept entire file changes |
Accept Block | Cmd+Y |
Ctrl+Y |
Accept individual code blocks |
Reject Changes | Cmd+Shift+Backspace |
Ctrl+Shift+Backspace |
Reject suggestions |
Autocomplete Accept | Tab |
Tab |
Accept autocompletion |
Autocomplete Reject | Escape |
Escape |
Reject autocompletion |
Platform-specific binaries:
Windows:
- sqlite-{version}-win32-x86.dll
- sqlite-{version}-win32-x86_64.dll
- sqlite-{version}-win32-aarch64.dll
macOS:
- libsqlite-{version}-osx-x86_64.dylib
- libsqlite-{version}-osx-aarch64.dylib (Apple Silicon)
Linux:
- libsqlite-{version}-linux-x86.so
- libsqlite-{version}-linux-x86_64.so
- libsqlite-{version}-linux-aarch64.so
- libsqlite-{version}-linux-musl-x86_64.so (Alpine Linux)
Cross-platform ANSI color support:
Windows: jansi-{version}-windows-x86.dll, jansi-{version}-windows-x86_64.dll
macOS: libjansi-{version}-osx-x86_64.dylib, libjansi-{version}-osx-aarch64.dylib
Linux: libjansi-{version}-linux-arm.so, libjansi-{version}-linux-x86_64.so
FreeBSD: libjansi-{version}-freebsd-x86.so, libjansi-{version}-freebsd-x86_64.so
// From BashTool.class security implementation
bannedCommands:
- Network tools: curl, wget, nc, telnet
- System utilities: rm -rf, format, fdisk
- Package managers: apt, yum, brew (in destructive contexts)
- Remote access: ssh, scp, rsync
securityMeasures:
- Command pattern matching
- User confirmation dialogs
- Auto-approval settings with user control
- Terminal session isolation
- Command timeout enforcement
- Interrupt capability (Ctrl+C)
// File system access controls
fileSecurityMeasures:
- Path validation and sanitization
- Project boundary enforcement
- Read-only vs write operation distinction
- VCS integration for change tracking
- Backup creation before modifications
- Permission checks before execution
// UI confirmation patterns
dialogOptions:
- Accept: Apply the suggested change
- Reject: Dismiss the suggestion
- Auto-Accept: Apply and enable auto-approval for similar operations
- Preview: Show detailed diff before decision
keyboardShortcuts:
- Enter: Quick accept
- Escape: Quick reject
- Cmd/Ctrl+Enter: Accept with auto-approval
// Chat UI components from decompiled classes
chatFeatures:
- Real-time streaming responses
- Message history persistence
- File reference (@file mentions)
- Context snippet management
- Apply/reject workflow for suggestions
- Conversation branching and forking
// File context integration
contextFeatures:
- Drag-and-drop file addition
- Right-click "Add to Sweep Chat" context menu
- Visual file snippet previews
- Line range selection and highlighting
- Automatic context relevance scoring
// Inline completion from AutocompleteEngine.class
autocompletionFeatures:
- Ghost text preview before acceptance
- Syntax-aware suggestions
- Context-based completion generation
- Tab-based acceptance workflow
- Edit tracking for improvement
- Conflict detection with other completion providers
// Trigger conditions for autocompletion
triggers:
- Typing pause detection
- Cursor position analysis
- Code context evaluation
- User interaction patterns
- File modification events
// Tutorial files for each supported language
tutorialLanguages:
- Java: "Welcome to Sweep AI! Try selecting code and pressing {CMD_J}"
- Kotlin: "Use {CMD_SHIFT_J} to add files to your conversation"
- Python: "Press Tab to accept suggestions, Escape to reject"
- TypeScript: "Use @filename to reference files in chat"
- C++: "Try asking Sweep to explain or improve your code"
- Ruby: "Sweep can help with debugging and optimization"
- Rust: "Use the terminal integration for build commands"
- Go: "Sweep understands Go idioms and best practices"
- C#: "Integration with .NET project structure"
// Context optimization strategies
contextOptimization:
- Lazy file loading based on relevance scores
- Heat map tracking for frequently accessed files
- Content truncation with preservation of important sections
- Token counting and context size management
- Intelligent snippet selection algorithms
// Multi-level caching system
cachingLayers:
- File content caching with invalidation
- Search result caching
- Tool parameter schema caching
- API response caching for repeated queries
- Metadata caching for project structure
// Non-blocking operation handling
asyncFeatures:
- Background API calls with progress indicators
- Non-blocking file operations
- Streaming response processing
- Concurrent tool execution where safe
- UI responsiveness during long operations
// Memory and resource optimization
resourceManagement:
- Phantom reference cleanup for API clients
- Connection pooling for HTTP requests
- Soft file descriptor limits
- Component lifecycle management
- Garbage collection optimization
// Deep IDE integration points
platformIntegration:
- PSI (Program Structure Interface) access for semantic analysis
- VFS (Virtual File System) integration for file operations
- Editor integration for real-time modifications
- Project structure awareness and navigation
- VCS integration (Git operations)
- Problem detection and quick-fix integration
// Plugin lifecycle management
componentLifecycle:
- Application-level services for global state
- Project-level services for project-specific operations
- Component disposal and cleanup
- Settings persistence and migration
- Plugin compatibility and conflict detection
// Language-specific configurations
supportedLanguages:
Java: {
fileExtensions: [".java"]
psiSupport: true
debuggerIntegration: true
buildSystemAwareness: ["Maven", "Gradle"]
}
Kotlin: {
fileExtensions: [".kt", ".kts"]
coroutineSupport: true
androidIntegration: true
multiplatformAwareness: true
}
Python: {
fileExtensions: [".py", ".pyw"]
virtualEnvDetection: true
packageManagerIntegration: ["pip", "conda"]
}
TypeScript: {
fileExtensions: [".ts", ".tsx"]
nodeModulesAwareness: true
tsConfigSupport: true
}
// Additional languages: C++, Ruby, Rust, Go, C#
// Extensibility features
extensionPoints:
- Custom tool implementation support
- MCP server integration framework
- Settings and configuration extension
- UI component customization
- Action and shortcut customization
// Settings and preferences
configurationOptions:
- API key and authentication settings
- Model selection and parameters
- Tool behavior customization
- Keyboard shortcut modification
- Auto-approval preferences
- Context management settings
The Sweep AI IntelliJ extension represents a sophisticated integration of conversational AI into the development workflow. Key architectural strengths include:
- Robust Tool System: 10 built-in tools with comprehensive IDE integration
- MCP Protocol Support: Extensible external tool ecosystem
- Advanced Context Management: Smart file selection and token optimization
- Cross-Platform Compatibility: Native support for Windows, macOS, and Linux
- Performance Optimization: Async operations, caching, and resource management
- Seamless IDE Integration: Deep platform integration without disrupting workflow
- Intelligent Autocompletion: Context-aware suggestions beyond traditional IntelliSense
- Visual Feedback: Diff previews and confirmation dialogs for user control
- Multi-Language Support: Comprehensive support for 9+ programming languages
- Claude 3.5 Sonnet Integration: Latest model with function calling capabilities
- Comprehensive System Prompt: Detailed behavioral instructions for code editing
- Context-Aware Conversations: File references and project structure awareness
- Tool Function Calling: Seamless integration between AI and development tools
- Command Filtering: Protection against dangerous terminal operations
- User Confirmation: Interactive approval for all destructive operations
- Sandboxed Execution: Secure tool execution within IDE constraints
- Audit Trail: Comprehensive logging and change tracking
The extension successfully balances powerful AI capabilities with user control, security, and performance, establishing a new standard for AI-powered development assistance in IDEs.
This analysis is based on complete decompilation of the Sweep AI IntelliJ extension (jetbrains-1.20.5.jar) and examination of all source code, configuration files, and dependencies.