Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions deployment/config/rag-pipeline/.env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@
QDRANT_URL=http://qdrant:6333
QDRANT_COLLECTION_PREFIX=codecrow

# ollama/openrouter
EMBEDDING_PROVIDER=openrouter
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_EMBEDDING_MODEL=qwen3-embedding:0.6b

# Ollama Performance Tuning
# Batch size for embedding requests (higher = better throughput, more memory)
OLLAMA_BATCH_SIZE=100
# Request timeout in seconds (increase for slow CPU)
OLLAMA_TIMEOUT=120

# CPU Threading Optimization (set based on your CPU cores)
# Recommended: physical_cores - 1 (leave 1 core for system)
OMP_NUM_THREADS=6
MKL_NUM_THREADS=6
OPENBLAS_NUM_THREADS=6

# OpenRouter Configuration
# Get your API key from https://openrouter.ai/
OPENROUTER_API_KEY=sk-or-v1-your-api-key-here
Expand Down
3 changes: 3 additions & 0 deletions deployment/config/web-frontend/.env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ VITE_WEBHOOK_URL=http://localhost:8082
VITE_GOOGLE_CLIENT_ID=YOUR_GOOGLE_CLIENT_ID
SERVER_PORT=8080

VITE_BLOG_URL=http://localhost:8083


# New Relic Browser Monitoring (Optional - leave empty to disable)
# Get these values from: https://one.newrelic.com -> Browser -> Add data -> Browser monitoring
# License Key: Use the BROWSER (Ingest) license key, NOT the main license key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
exports org.rostilos.codecrow.analysisengine.aiclient;
exports org.rostilos.codecrow.analysisengine.config;
exports org.rostilos.codecrow.analysisengine.dto.request.ai;
exports org.rostilos.codecrow.analysisengine.dto.request.ai.enrichment;
exports org.rostilos.codecrow.analysisengine.dto.request.processor;
exports org.rostilos.codecrow.analysisengine.dto.request.validation;
exports org.rostilos.codecrow.analysisengine.exception;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.rostilos.codecrow.analysisengine.dto.request.ai;

import com.fasterxml.jackson.annotation.JsonProperty;
import org.rostilos.codecrow.analysisengine.dto.request.ai.enrichment.PrEnrichmentDataDto;
import org.rostilos.codecrow.core.model.ai.AIConnection;
import org.rostilos.codecrow.core.model.ai.AIProviderKey;
import org.rostilos.codecrow.core.model.codeanalysis.AnalysisMode;
Expand Down Expand Up @@ -44,6 +45,9 @@ public class AiAnalysisRequestImpl implements AiAnalysisRequest{
protected final String deltaDiff;
protected final String previousCommitHash;
protected final String currentCommitHash;

// File enrichment data (full file contents + dependency graph)
protected final PrEnrichmentDataDto enrichmentData;

protected AiAnalysisRequestImpl(Builder<?> builder) {
this.projectId = builder.projectId;
Expand Down Expand Up @@ -74,6 +78,8 @@ protected AiAnalysisRequestImpl(Builder<?> builder) {
this.deltaDiff = builder.deltaDiff;
this.previousCommitHash = builder.previousCommitHash;
this.currentCommitHash = builder.currentCommitHash;
// File enrichment data
this.enrichmentData = builder.enrichmentData;
}

public Long getProjectId() {
Expand Down Expand Up @@ -181,6 +187,10 @@ public String getCurrentCommitHash() {
return currentCommitHash;
}

public PrEnrichmentDataDto getEnrichmentData() {
return enrichmentData;
}


public static Builder<?> builder() {
return new Builder<>();
Expand Down Expand Up @@ -216,6 +226,8 @@ public static class Builder<T extends Builder<T>> {
private String deltaDiff;
private String previousCommitHash;
private String currentCommitHash;
// File enrichment data
private PrEnrichmentDataDto enrichmentData;

protected Builder() {
}
Expand Down Expand Up @@ -461,6 +473,11 @@ public T withCurrentCommitHash(String currentCommitHash) {
return self();
}

public T withEnrichmentData(PrEnrichmentDataDto enrichmentData) {
this.enrichmentData = enrichmentData;
return self();
}

public AiAnalysisRequestImpl build() {
return new AiAnalysisRequestImpl(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.rostilos.codecrow.analysisengine.dto.request.ai.enrichment;

/**
* DTO representing the content of a single file retrieved from VCS.
* Used for file enrichment during PR analysis to provide full file context.
*/
public record FileContentDto(
String path,
String content,
long sizeBytes,
boolean skipped,
String skipReason
) {
/**
* Create a successful file content result.
*/
public static FileContentDto of(String path, String content) {
return new FileContentDto(
path,
content,
content != null ? content.getBytes().length : 0,
false,
null
);
}

/**
* Create a skipped file result (e.g., file too large, binary, or fetch failed).
*/
public static FileContentDto skipped(String path, String reason) {
return new FileContentDto(path, null, 0, true, reason);
}

/**
* Create a skipped file result due to size limit.
*/
public static FileContentDto skippedDueToSize(String path, long actualSize, long maxSize) {
return new FileContentDto(
path,
null,
actualSize,
true,
String.format("File size %d bytes exceeds limit %d bytes", actualSize, maxSize)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.rostilos.codecrow.analysisengine.dto.request.ai.enrichment;

/**
* DTO representing a relationship between two files in the PR.
* Used for building the dependency graph for intelligent batching.
*/
public record FileRelationshipDto(
String sourceFile,
String targetFile,
RelationshipType relationshipType,
String matchedOn,
int strength
) {
/**
* Types of relationships between files.
*/
public enum RelationshipType {
IMPORTS,
EXTENDS,
IMPLEMENTS,
CALLS,
SAME_PACKAGE,
REFERENCES
}

/**
* Create an import relationship.
*/
public static FileRelationshipDto imports(String sourceFile, String targetFile, String importStatement) {
return new FileRelationshipDto(
sourceFile,
targetFile,
RelationshipType.IMPORTS,
importStatement,
10 // High strength for direct imports
);
}

/**
* Create an extends relationship.
*/
public static FileRelationshipDto extendsClass(String sourceFile, String targetFile, String className) {
return new FileRelationshipDto(
sourceFile,
targetFile,
RelationshipType.EXTENDS,
className,
15 // Highest strength for inheritance
);
}

/**
* Create an implements relationship.
*/
public static FileRelationshipDto implementsInterface(String sourceFile, String targetFile, String interfaceName) {
return new FileRelationshipDto(
sourceFile,
targetFile,
RelationshipType.IMPLEMENTS,
interfaceName,
15 // Highest strength for interface implementation
);
}

/**
* Create a calls relationship.
*/
public static FileRelationshipDto calls(String sourceFile, String targetFile, String methodName) {
return new FileRelationshipDto(
sourceFile,
targetFile,
RelationshipType.CALLS,
methodName,
8 // Medium-high strength for method calls
);
}

/**
* Create a same-package relationship.
*/
public static FileRelationshipDto samePackage(String sourceFile, String targetFile, String packageName) {
return new FileRelationshipDto(
sourceFile,
targetFile,
RelationshipType.SAME_PACKAGE,
packageName,
3 // Low strength for implicit package relationship
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package org.rostilos.codecrow.analysisengine.dto.request.ai.enrichment;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.List;

/**
* DTO representing parsed AST metadata for a single file.
* Mirrors the response from RAG pipeline's /parse endpoint.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public record ParsedFileMetadataDto(
@JsonProperty("path") String path,
@JsonProperty("language") String language,
@JsonProperty("imports") List<String> imports,
@JsonProperty("extends") List<String> extendsClasses,
@JsonProperty("implements") List<String> implementsInterfaces,
@JsonProperty("semantic_names") List<String> semanticNames,
@JsonProperty("parent_class") String parentClass,
@JsonProperty("namespace") String namespace,
@JsonProperty("calls") List<String> calls,
@JsonProperty("error") String error
) {
/**
* Create a metadata result with only imports and extends (minimal parsing).
*/
public static ParsedFileMetadataDto minimal(String path, List<String> imports, List<String> extendsClasses) {
return new ParsedFileMetadataDto(
path,
null,
imports,
extendsClasses,
List.of(),
List.of(),
null,
null,
List.of(),
null
);
}

/**
* Create an error result for a file that couldn't be parsed.
*/
public static ParsedFileMetadataDto error(String path, String errorMessage) {
return new ParsedFileMetadataDto(
path,
null,
List.of(),
List.of(),
List.of(),
List.of(),
null,
null,
List.of(),
errorMessage
);
}

/**
* Check if this metadata has any relationships to extract.
*/
public boolean hasRelationships() {
return (imports != null && !imports.isEmpty()) ||
(extendsClasses != null && !extendsClasses.isEmpty()) ||
(implementsInterfaces != null && !implementsInterfaces.isEmpty()) ||
(calls != null && !calls.isEmpty());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.rostilos.codecrow.analysisengine.dto.request.ai.enrichment;

import java.util.List;
import java.util.Map;

/**
* Aggregate DTO containing all file enrichment data for a PR.
* This is the result of the enrichment process and can be serialized for transfer.
*/
public record PrEnrichmentDataDto(
List<FileContentDto> fileContents,
List<ParsedFileMetadataDto> fileMetadata,
List<FileRelationshipDto> relationships,
EnrichmentStats stats
) {
/**
* Statistics about the enrichment process.
*/
public record EnrichmentStats(
int totalFilesRequested,
int filesEnriched,
int filesSkipped,
int relationshipsFound,
long totalContentSizeBytes,
long processingTimeMs,
Map<String, Integer> skipReasons
) {
public static EnrichmentStats empty() {
return new EnrichmentStats(0, 0, 0, 0, 0, 0, Map.of());
}
}

/**
* Create empty enrichment data (when enrichment is disabled or not applicable).
*/
public static PrEnrichmentDataDto empty() {
return new PrEnrichmentDataDto(
List.of(),
List.of(),
List.of(),
EnrichmentStats.empty()
);
}

/**
* Check if enrichment data is present.
*/
public boolean hasData() {
return (fileContents != null && !fileContents.isEmpty()) ||
(relationships != null && !relationships.isEmpty());
}

/**
* Get total size of all file contents in bytes.
*/
public long getTotalContentSize() {
if (fileContents == null) return 0;
return fileContents.stream()
.filter(f -> !f.skipped())
.mapToLong(FileContentDto::sizeBytes)
.sum();
}
}
Loading