Support for structured output

Added support for structured output
This commit is contained in:
amithkoujalgi
2025-03-24 00:25:20 +05:30
parent e62a7511db
commit b9b18271a1
7 changed files with 1304 additions and 715 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,26 @@
package io.github.ollama4j.models.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.Data;
import lombok.Getter;
import static io.github.ollama4j.utils.Utils.getObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.Data;
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
/** The type Ollama result. */
@Getter
@SuppressWarnings("unused")
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class OllamaResult {
/**
* -- GETTER --
* Get the completion/response text
* Get the completion/response text
*
* @return String completion/response text
*/
@@ -21,7 +28,7 @@ public class OllamaResult {
/**
* -- GETTER --
* Get the response status code.
* Get the response status code.
*
* @return int - response status code
*/
@@ -29,7 +36,7 @@ public class OllamaResult {
/**
* -- GETTER --
* Get the response time in milliseconds.
* Get the response time in milliseconds.
*
* @return long - response time in milliseconds
*/
@@ -44,9 +51,68 @@ public class OllamaResult {
@Override
public String toString() {
try {
return getObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(this);
Map<String, Object> responseMap = new HashMap<>();
responseMap.put("response", this.response);
responseMap.put("httpStatusCode", this.httpStatusCode);
responseMap.put("responseTime", this.responseTime);
return getObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(responseMap);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
/**
* Get the structured response if the response is a JSON object.
*
* @return Map - structured response
* @throws IllegalArgumentException if the response is not a valid JSON object
*/
public Map<String, Object> getStructuredResponse() {
String responseStr = this.getResponse();
if (responseStr == null || responseStr.trim().isEmpty()) {
throw new IllegalArgumentException("Response is empty or null");
}
try {
// Check if the response is a valid JSON
if ((!responseStr.trim().startsWith("{") && !responseStr.trim().startsWith("[")) ||
(!responseStr.trim().endsWith("}") && !responseStr.trim().endsWith("]"))) {
throw new IllegalArgumentException("Response is not a valid JSON object");
}
Map<String, Object> response = getObjectMapper().readValue(responseStr,
new TypeReference<Map<String, Object>>() {
});
return response;
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Failed to parse response as JSON: " + e.getMessage(), e);
}
}
/**
* Get the structured response mapped to a specific class type.
*
* @param <T> The type of class to map the response to
* @param clazz The class to map the response to
* @return An instance of the specified class with the response data
* @throws IllegalArgumentException if the response is not a valid JSON or is empty
* @throws RuntimeException if there is an error mapping the response
*/
public <T> T as(Class<T> clazz) {
String responseStr = this.getResponse();
if (responseStr == null || responseStr.trim().isEmpty()) {
throw new IllegalArgumentException("Response is empty or null");
}
try {
// Check if the response is a valid JSON
if ((!responseStr.trim().startsWith("{") && !responseStr.trim().startsWith("[")) ||
(!responseStr.trim().endsWith("}") && !responseStr.trim().endsWith("]"))) {
throw new IllegalArgumentException("Response is not a valid JSON object");
}
return getObjectMapper().readValue(responseStr, clazz);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Failed to parse response as JSON: " + e.getMessage(), e);
}
}
}

View File

@@ -0,0 +1,77 @@
package io.github.ollama4j.models.response;
import static io.github.ollama4j.utils.Utils.getObjectMapper;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@SuppressWarnings("unused")
@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class OllamaStructuredResult {
private String response;
private int httpStatusCode;
private long responseTime = 0;
private String model;
public OllamaStructuredResult(String response, long responseTime, int httpStatusCode) {
this.response = response;
this.responseTime = responseTime;
this.httpStatusCode = httpStatusCode;
}
@Override
public String toString() {
try {
return getObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(this);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
/**
* Get the structured response if the response is a JSON object.
*
* @return Map - structured response
*/
public Map<String, Object> getStructuredResponse() {
try {
Map<String, Object> response = getObjectMapper().readValue(this.getResponse(),
new TypeReference<Map<String, Object>>() {
});
return response;
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
/**
* Get the structured response mapped to a specific class type.
*
* @param <T> The type of class to map the response to
* @param clazz The class to map the response to
* @return An instance of the specified class with the response data
* @throws RuntimeException if there is an error mapping the response
*/
public <T> T getStructuredResponse(Class<T> clazz) {
try {
return getObjectMapper().readValue(this.getResponse(), clazz);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}