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
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.5</version>
<version>4.1.0</version>
<relativePath/>
</parent>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.remus.giteabot.agent.critic;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.remus.giteabot.agent.shared.AgentMetricsHolder;
import org.remus.giteabot.ai.AiClient;
Expand Down Expand Up @@ -120,9 +120,9 @@ ReflectionResult parseResponse(String response) {
String json = extractJson(response);
try {
JsonNode node = objectMapper.readTree(json);
String outcome = node.path("outcome").asText("APPROVE")
String outcome = node.path("outcome").asString("APPROVE")
.trim().toUpperCase(Locale.ROOT);
String feedback = node.path("feedback").asText("").trim();
String feedback = node.path("feedback").asString("").trim();
return switch (outcome) {
case "ITERATE" -> ReflectionResult.iterate(feedback);
case "ABORT" -> ReflectionResult.abort(feedback);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,63 +137,6 @@ public ImplementationPlan parseAiResponse(String aiResponse) {
}
}

/**
* Parses the AI's response for requested files, validating them against the repository tree.
*
* @param aiResponse The raw AI response
* @param tree The repository file tree
* @return List of valid requested file paths
*/
public List<String> parseRequestedFiles(String aiResponse, List<Map<String, Object>> tree) {
List<String> requestedFiles = new ArrayList<>();

// Build set of valid paths
Set<String> validPaths = new HashSet<>();
for (Map<String, Object> entry : tree) {
String path = (String) entry.getOrDefault("path", "");
String type = (String) entry.getOrDefault("type", "blob");
if ("blob".equals(type)) {
validPaths.add(path);
}
}

// Try to extract JSON from response
String jsonStr = extractJsonFromResponse(aiResponse);
if (jsonStr != null) {
jsonStr = truncateToFirstJsonObject(jsonStr);
try {
FileRequestResponse response = objectMapper.readValue(jsonStr, FileRequestResponse.class);
if (response != null && response.getRequestedFiles() != null) {
for (String file : response.getRequestedFiles()) {
if (validPaths.contains(file)) {
requestedFiles.add(file);
} else {
log.debug("Requested file not found in tree: {}", file);
}
}
}
} catch (JacksonException e) {
log.warn("Failed to parse file request response: {}", e.getMessage());
}
}

// If parsing failed, fall back to pattern matching
if (requestedFiles.isEmpty()) {
for (String path : validPaths) {
if (aiResponse.contains(path)) {
requestedFiles.add(path);
}
}
}

// Limit to 30 files
if (requestedFiles.size() > 30) {
requestedFiles = requestedFiles.subList(0, 30);
}

return requestedFiles;
}

/**
* Extracts the non-JSON (thinking/reasoning) text from an AI response.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.remus.giteabot.ai.google;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.remus.giteabot.agent.shared.AgentJackson;
import org.remus.giteabot.ai.AbstractAiClient;
Expand Down Expand Up @@ -423,10 +423,9 @@ private String extractGoogleErrorMessage(String responseBody) {
}
try {
JsonNode message = OBJECT_MAPPER.readTree(responseBody).path("error").path("message");
return message.isTextual() ? message.asText() : null;
return message.isString() ? message.asString() : null;
} catch (Exception ignored) {
return null;
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,3 @@ public static class FunctionDeclaration {
private Object parameters;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,3 @@ public static class UsageMetadata {
private int totalTokenCount;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,3 @@ public static class Timings {
private Double predictedMs;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,3 @@ public static class FunctionCall {
private Map<String, Object> arguments;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,3 @@ public static class FunctionResponse {
private Map<String, Object> arguments;
}
}

2 changes: 0 additions & 2 deletions src/main/java/org/remus/giteabot/ai/openai/OpenAiRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,3 @@ public static class FunctionCall {
private String arguments;
}
}


17 changes: 8 additions & 9 deletions src/main/java/org/remus/giteabot/aiusage/AiUsageService.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package org.remus.giteabot.aiusage;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tools.jackson.core.JsonGenerator;

import java.io.IOException;
import java.io.OutputStream;
Expand Down Expand Up @@ -119,11 +118,11 @@ public Page<AiErrorLog> findErrors(Instant from, Instant to, int page,
* the correct pattern for streaming responses that outlive a single
* transaction.</p>
*/
public void exportErrors(Instant from, Instant to, OutputStream outputStream) throws IOException {
public void exportErrors(Instant from, Instant to, OutputStream outputStream) {
Instant f = effectiveFrom(from);
Instant t = effectiveTo(to);

try (JsonGenerator gen = new ObjectMapper().getFactory().createGenerator(outputStream)) {
try (JsonGenerator gen = tools.jackson.core.ObjectWriteContext.empty().createGenerator(outputStream)) {
gen.writeStartArray();
int page = 0;
Page<AiErrorLog> result;
Expand All @@ -132,11 +131,11 @@ public void exportErrors(Instant from, Instant to, OutputStream outputStream) th
f, t, PageRequest.of(page, EXPORT_PAGE_SIZE));
for (AiErrorLog entry : result.getContent()) {
gen.writeStartObject();
gen.writeObjectField("timestamp", entry.getTimestamp());
gen.writeStringField("aiIntegration", entry.getAiIntegrationName());
gen.writeStringField("sessionId", entry.getSessionId());
gen.writeStringField("errorMessage", entry.getErrorMessage());
gen.writeStringField("stackTrace", entry.getStackTrace());
gen.writePOJOProperty("timestamp", entry.getTimestamp());
gen.writeStringProperty("aiIntegration", entry.getAiIntegrationName());
gen.writeStringProperty("sessionId", entry.getSessionId());
gen.writeStringProperty("errorMessage", entry.getErrorMessage());
gen.writeStringProperty("stackTrace", entry.getStackTrace());
gen.writeEndObject();
}
gen.flush();
Expand Down
13 changes: 6 additions & 7 deletions src/main/java/org/remus/giteabot/mcp/McpConfigurationParser.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.remus.giteabot.mcp;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
Expand Down Expand Up @@ -62,8 +62,8 @@ private McpServerDefinition toServerDefinition(String fallbackName, JsonNode nod
JsonNode headersNode = node.get("headers");
if (headersNode != null && headersNode.isObject()) {
headersNode.properties().forEach(field -> {
if (field.getValue().isTextual()) {
headers.put(field.getKey(), field.getValue().asText());
if (field.getValue().isString()) {
headers.put(field.getKey(), field.getValue().asString());
}
});
}
Expand All @@ -72,10 +72,9 @@ private McpServerDefinition toServerDefinition(String fallbackName, JsonNode nod

private String text(JsonNode node, String field, String defaultValue) {
JsonNode value = node.get(field);
if (value != null && value.isTextual() && !value.asText().isBlank()) {
return value.asText().strip();
if (value != null && value.isString() && !value.asString().isBlank()) {
return value.asString().strip();
}
return defaultValue;
}
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.remus.giteabot.mcp;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import tools.jackson.core.type.TypeReference;
import tools.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.McpSyncClient;
import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
Expand Down Expand Up @@ -474,5 +474,3 @@ String describe() {
}
}
}


Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.remus.giteabot.mcp;

import com.fasterxml.jackson.databind.ObjectMapper;
import tools.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
Expand Down Expand Up @@ -50,4 +50,3 @@ private String schemaToString(Map<String, Object> schema) {
}
}
}

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.remus.giteabot.prworkflow.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import tools.jackson.databind.ObjectMapper;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.remus.giteabot.prworkflow.deployment;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.node.ObjectNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.remus.giteabot.admin.Bot;
Expand Down Expand Up @@ -242,7 +242,7 @@ private Map<String, String> renderInputs(JsonNode inputsNode, DeploymentRequest
Map<String, String> out = new LinkedHashMap<>();
inputsNode.properties().forEach(entry -> {
String value = entry.getValue() == null || entry.getValue().isNull()
? "" : entry.getValue().asText();
? "" : entry.getValue().asString();
out.put(entry.getKey(), applyPlaceholders(value, request));
});
return out;
Expand Down Expand Up @@ -270,7 +270,7 @@ static int clampPollInterval(int seconds) {
private static String textOrNull(JsonNode node, String field) {
if (node == null) return null;
JsonNode v = node.get(field);
return (v == null || v.isNull()) ? null : v.asText();
return (v == null || v.isNull()) ? null : v.asString();
}

private static String textOr(JsonNode node, String field, String fallback) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.remus.giteabot.prworkflow.deployment;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

Expand Down Expand Up @@ -109,7 +109,7 @@ public DeploymentResult trigger(DeploymentRequest request) {
JsonNode extra = config.get(CONFIG_EXTRA_HEADERS);
if (extra != null && extra.isObject()) {
extra.properties().iterator().forEachRemaining(entry ->
builder.header(entry.getKey(), entry.getValue().asText()));
builder.header(entry.getKey(), entry.getValue().asString()));
}
HttpResponse<Void> response = httpClient.send(builder.build(),
HttpResponse.BodyHandlers.discarding());
Expand Down Expand Up @@ -140,7 +140,7 @@ public DeploymentResult trigger(DeploymentRequest request) {

private static String textOr(JsonNode node, String field, String fallback) {
JsonNode v = node == null ? null : node.get(field);
return (v == null || v.isNull()) ? fallback : v.asText();
return (v == null || v.isNull()) ? fallback : v.asString();
}

private static int intOr(JsonNode node, String field, int fallback) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.remus.giteabot.prworkflow.deployment;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

Expand Down Expand Up @@ -130,7 +130,7 @@ public DeploymentResult trigger(DeploymentRequest request) {
JsonNode headers = config.get(CONFIG_HEADERS);
if (headers != null && headers.isObject()) {
headers.properties().iterator().forEachRemaining(entry ->
builder.header(entry.getKey(), entry.getValue().asText()));
builder.header(entry.getKey(), entry.getValue().asString()));
}

try {
Expand Down Expand Up @@ -168,7 +168,7 @@ private static String textOrNull(JsonNode node, String field) {
return null;
}
JsonNode v = node.get(field);
return (v == null || v.isNull()) ? null : v.asText();
return (v == null || v.isNull()) ? null : v.asString();
}

private static String truncate(String body) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.remus.giteabot.prworkflow.deployment;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.remus.giteabot.prworkflow.PrWorkflowRun;
Expand Down Expand Up @@ -161,7 +161,7 @@ private static ResponseEntity<String> unauthorized() {

private static String textOrNull(JsonNode node, String field) {
JsonNode v = node == null ? null : node.get(field);
return (v == null || v.isNull()) ? null : v.asText();
return (v == null || v.isNull()) ? null : v.asString();
}

private static boolean constantTimeEquals(String expected, String provided) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.remus.giteabot.prworkflow.deployment.mcp;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import tools.jackson.core.type.TypeReference;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.remus.giteabot.agent.validation.ToolResult;
Expand Down Expand Up @@ -363,7 +363,7 @@ static HandleSummary parseHandle(String handleJson) {

private static String textOrNull(JsonNode node, String field) {
JsonNode v = node.get(field);
return (v == null || v.isNull()) ? null : v.asText();
return (v == null || v.isNull()) ? null : v.asString();
}
}

Loading
Loading