mirror of
https://github.com/amithkoujalgi/ollama4j.git
synced 2025-05-14 19:37:11 +02:00
- Updated Makefile to add a new remote integration test command.
- Updated docs – Enhanced DBQueryFunction to validate input arguments and throw a RuntimeException if required arguments are missing. - Updated docs – Refactored tool specifications for fuel price, weather, and employee details to use a unified prompt function structure. (Addresses #116). - Improved javadoc for `chatStreaming()` API. (Addresses #115). - Introduced `ToolInvocationException` to handle errors during tool invocation in OllamaAPI. (Addresses #117). - Updated integration tests to include `ToolInvocationException` in method signatures for better error handling.
This commit is contained in:
parent
70b4a7961a
commit
a2d95a052a
4
Makefile
4
Makefile
@ -18,8 +18,8 @@ unit-tests:
|
|||||||
integration-tests:
|
integration-tests:
|
||||||
export USE_EXTERNAL_OLLAMA_HOST=false && mvn clean verify -Pintegration-tests
|
export USE_EXTERNAL_OLLAMA_HOST=false && mvn clean verify -Pintegration-tests
|
||||||
|
|
||||||
integration-tests-local:
|
integration-tests-remote:
|
||||||
export USE_EXTERNAL_OLLAMA_HOST=true && export OLLAMA_HOST=http://localhost:11434 && mvn clean verify -Pintegration-tests -Dgpg.skip=true
|
export USE_EXTERNAL_OLLAMA_HOST=true && export OLLAMA_HOST=http://192.168.29.223:11434 && mvn clean verify -Pintegration-tests -Dgpg.skip=true
|
||||||
|
|
||||||
doxygen:
|
doxygen:
|
||||||
doxygen Doxyfile
|
doxygen Doxyfile
|
||||||
|
@ -61,6 +61,9 @@ details.
|
|||||||
class DBQueryFunction implements ToolFunction {
|
class DBQueryFunction implements ToolFunction {
|
||||||
@Override
|
@Override
|
||||||
public Object apply(Map<String, Object> arguments) {
|
public Object apply(Map<String, Object> arguments) {
|
||||||
|
if (arguments == null || arguments.isEmpty() || arguments.get("employee-name") == null || arguments.get("employee-address") == null || arguments.get("employee-phone") == null) {
|
||||||
|
throw new RuntimeException("Tool was called but the model failed to provide all the required arguments.");
|
||||||
|
}
|
||||||
// perform DB operations here
|
// perform DB operations here
|
||||||
return String.format("Employee Details {ID: %s, Name: %s, Address: %s, Phone: %s}", UUID.randomUUID(), arguments.get("employee-name").toString(), arguments.get("employee-address").toString(), arguments.get("employee-phone").toString());
|
return String.format("Employee Details {ID: %s, Name: %s, Address: %s, Phone: %s}", UUID.randomUUID(), arguments.get("employee-name").toString(), arguments.get("employee-address").toString(), arguments.get("employee-phone").toString());
|
||||||
}
|
}
|
||||||
@ -78,14 +81,39 @@ Lets define a sample tool specification called **Fuel Price Tool** for getting t
|
|||||||
Tools.ToolSpecification fuelPriceToolSpecification = Tools.ToolSpecification.builder()
|
Tools.ToolSpecification fuelPriceToolSpecification = Tools.ToolSpecification.builder()
|
||||||
.functionName("current-fuel-price")
|
.functionName("current-fuel-price")
|
||||||
.functionDescription("Get current fuel price")
|
.functionDescription("Get current fuel price")
|
||||||
|
.toolFunction(SampleTools::getCurrentFuelPrice)
|
||||||
|
.toolPrompt(
|
||||||
|
Tools.PromptFuncDefinition.builder()
|
||||||
|
.type("prompt")
|
||||||
|
.function(
|
||||||
|
Tools.PromptFuncDefinition.PromptFuncSpec.builder()
|
||||||
|
.name("get-location-fuel-info")
|
||||||
|
.description("Get location and fuel type details")
|
||||||
|
.parameters(
|
||||||
|
Tools.PromptFuncDefinition.Parameters.builder()
|
||||||
|
.type("object")
|
||||||
.properties(
|
.properties(
|
||||||
new Tools.PropsBuilder()
|
Map.of(
|
||||||
.withProperty("location", Tools.PromptFuncDefinition.Property.builder().type("string").description("The city, e.g. New Delhi, India").required(true).build())
|
"location", Tools.PromptFuncDefinition.Property.builder()
|
||||||
.withProperty("fuelType", Tools.PromptFuncDefinition.Property.builder().type("string").description("The fuel type.").enumValues(Arrays.asList("petrol", "diesel")).required(true).build())
|
.type("string")
|
||||||
|
.description("The city, e.g. New Delhi, India")
|
||||||
|
.required(true)
|
||||||
|
.build(),
|
||||||
|
"fuelType", Tools.PromptFuncDefinition.Property.builder()
|
||||||
|
.type("string")
|
||||||
|
.description("The fuel type.")
|
||||||
|
.enumValues(Arrays.asList("petrol", "diesel"))
|
||||||
|
.required(true)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.toolDefinition(SampleTools::getCurrentFuelPrice)
|
)
|
||||||
.build();
|
.required(java.util.List.of("location", "fuelType"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
).build();
|
||||||
```
|
```
|
||||||
|
|
||||||
Lets also define a sample tool specification called **Weather Tool** for getting the current weather.
|
Lets also define a sample tool specification called **Weather Tool** for getting the current weather.
|
||||||
@ -97,13 +125,33 @@ Lets also define a sample tool specification called **Weather Tool** for getting
|
|||||||
Tools.ToolSpecification weatherToolSpecification = Tools.ToolSpecification.builder()
|
Tools.ToolSpecification weatherToolSpecification = Tools.ToolSpecification.builder()
|
||||||
.functionName("current-weather")
|
.functionName("current-weather")
|
||||||
.functionDescription("Get current weather")
|
.functionDescription("Get current weather")
|
||||||
|
.toolFunction(SampleTools::getCurrentWeather)
|
||||||
|
.toolPrompt(
|
||||||
|
Tools.PromptFuncDefinition.builder()
|
||||||
|
.type("prompt")
|
||||||
|
.function(
|
||||||
|
Tools.PromptFuncDefinition.PromptFuncSpec.builder()
|
||||||
|
.name("get-location-weather-info")
|
||||||
|
.description("Get location details")
|
||||||
|
.parameters(
|
||||||
|
Tools.PromptFuncDefinition.Parameters.builder()
|
||||||
|
.type("object")
|
||||||
.properties(
|
.properties(
|
||||||
new Tools.PropsBuilder()
|
Map.of(
|
||||||
.withProperty("city", Tools.PromptFuncDefinition.Property.builder().type("string").description("The city, e.g. New Delhi, India").required(true).build())
|
"city", Tools.PromptFuncDefinition.Property.builder()
|
||||||
|
.type("string")
|
||||||
|
.description("The city, e.g. New Delhi, India")
|
||||||
|
.required(true)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.toolDefinition(SampleTools::getCurrentWeather)
|
)
|
||||||
.build();
|
.required(java.util.List.of("city"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
).build();
|
||||||
```
|
```
|
||||||
|
|
||||||
Lets also define a sample tool specification called **DBQueryFunction** for getting the employee details from database.
|
Lets also define a sample tool specification called **DBQueryFunction** for getting the employee details from database.
|
||||||
@ -115,14 +163,43 @@ Lets also define a sample tool specification called **DBQueryFunction** for gett
|
|||||||
Tools.ToolSpecification databaseQueryToolSpecification = Tools.ToolSpecification.builder()
|
Tools.ToolSpecification databaseQueryToolSpecification = Tools.ToolSpecification.builder()
|
||||||
.functionName("get-employee-details")
|
.functionName("get-employee-details")
|
||||||
.functionDescription("Get employee details from the database")
|
.functionDescription("Get employee details from the database")
|
||||||
|
.toolFunction(new DBQueryFunction())
|
||||||
|
.toolPrompt(
|
||||||
|
Tools.PromptFuncDefinition.builder()
|
||||||
|
.type("prompt")
|
||||||
|
.function(
|
||||||
|
Tools.PromptFuncDefinition.PromptFuncSpec.builder()
|
||||||
|
.name("get-employee-details")
|
||||||
|
.description("Get employee details from the database")
|
||||||
|
.parameters(
|
||||||
|
Tools.PromptFuncDefinition.Parameters.builder()
|
||||||
|
.type("object")
|
||||||
.properties(
|
.properties(
|
||||||
new Tools.PropsBuilder()
|
Map.of(
|
||||||
.withProperty("employee-name", Tools.PromptFuncDefinition.Property.builder().type("string").description("The name of the employee, e.g. John Doe").required(true).build())
|
"employee-name", Tools.PromptFuncDefinition.Property.builder()
|
||||||
.withProperty("employee-address", Tools.PromptFuncDefinition.Property.builder().type("string").description("The address of the employee, Always return a random value. e.g. Roy St, Bengaluru, India").required(true).build())
|
.type("string")
|
||||||
.withProperty("employee-phone", Tools.PromptFuncDefinition.Property.builder().type("string").description("The phone number of the employee. Always return a random value. e.g. 9911002233").required(true).build())
|
.description("The name of the employee, e.g. John Doe")
|
||||||
|
.required(true)
|
||||||
|
.build(),
|
||||||
|
"employee-address", Tools.PromptFuncDefinition.Property.builder()
|
||||||
|
.type("string")
|
||||||
|
.description("The address of the employee, Always return a random value. e.g. Roy St, Bengaluru, India")
|
||||||
|
.required(true)
|
||||||
|
.build(),
|
||||||
|
"employee-phone", Tools.PromptFuncDefinition.Property.builder()
|
||||||
|
.type("string")
|
||||||
|
.description("The phone number of the employee. Always return a random value. e.g. 9911002233")
|
||||||
|
.required(true)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.required(java.util.List.of("employee-name", "employee-address", "employee-phone"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.toolDefinition(new DBQueryFunction())
|
|
||||||
.build();
|
.build();
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -239,37 +316,111 @@ public class FunctionCallingWithMistralExample {
|
|||||||
Tools.ToolSpecification fuelPriceToolSpecification = Tools.ToolSpecification.builder()
|
Tools.ToolSpecification fuelPriceToolSpecification = Tools.ToolSpecification.builder()
|
||||||
.functionName("current-fuel-price")
|
.functionName("current-fuel-price")
|
||||||
.functionDescription("Get current fuel price")
|
.functionDescription("Get current fuel price")
|
||||||
|
.toolFunction(SampleTools::getCurrentFuelPrice)
|
||||||
|
.toolPrompt(
|
||||||
|
Tools.PromptFuncDefinition.builder()
|
||||||
|
.type("prompt")
|
||||||
|
.function(
|
||||||
|
Tools.PromptFuncDefinition.PromptFuncSpec.builder()
|
||||||
|
.name("get-location-fuel-info")
|
||||||
|
.description("Get location and fuel type details")
|
||||||
|
.parameters(
|
||||||
|
Tools.PromptFuncDefinition.Parameters.builder()
|
||||||
|
.type("object")
|
||||||
.properties(
|
.properties(
|
||||||
new Tools.PropsBuilder()
|
Map.of(
|
||||||
.withProperty("location", Tools.PromptFuncDefinition.Property.builder().type("string").description("The city, e.g. New Delhi, India").required(true).build())
|
"location", Tools.PromptFuncDefinition.Property.builder()
|
||||||
.withProperty("fuelType", Tools.PromptFuncDefinition.Property.builder().type("string").description("The fuel type.").enumValues(Arrays.asList("petrol", "diesel")).required(true).build())
|
.type("string")
|
||||||
|
.description("The city, e.g. New Delhi, India")
|
||||||
|
.required(true)
|
||||||
|
.build(),
|
||||||
|
"fuelType", Tools.PromptFuncDefinition.Property.builder()
|
||||||
|
.type("string")
|
||||||
|
.description("The fuel type.")
|
||||||
|
.enumValues(Arrays.asList("petrol", "diesel"))
|
||||||
|
.required(true)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.toolDefinition(SampleTools::getCurrentFuelPrice)
|
)
|
||||||
.build();
|
.required(java.util.List.of("location", "fuelType"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
).build();
|
||||||
|
|
||||||
Tools.ToolSpecification weatherToolSpecification = Tools.ToolSpecification.builder()
|
Tools.ToolSpecification weatherToolSpecification = Tools.ToolSpecification.builder()
|
||||||
.functionName("current-weather")
|
.functionName("current-weather")
|
||||||
.functionDescription("Get current weather")
|
.functionDescription("Get current weather")
|
||||||
|
.toolFunction(SampleTools::getCurrentWeather)
|
||||||
|
.toolPrompt(
|
||||||
|
Tools.PromptFuncDefinition.builder()
|
||||||
|
.type("prompt")
|
||||||
|
.function(
|
||||||
|
Tools.PromptFuncDefinition.PromptFuncSpec.builder()
|
||||||
|
.name("get-location-weather-info")
|
||||||
|
.description("Get location details")
|
||||||
|
.parameters(
|
||||||
|
Tools.PromptFuncDefinition.Parameters.builder()
|
||||||
|
.type("object")
|
||||||
.properties(
|
.properties(
|
||||||
new Tools.PropsBuilder()
|
Map.of(
|
||||||
.withProperty("city", Tools.PromptFuncDefinition.Property.builder().type("string").description("The city, e.g. New Delhi, India").required(true).build())
|
"city", Tools.PromptFuncDefinition.Property.builder()
|
||||||
|
.type("string")
|
||||||
|
.description("The city, e.g. New Delhi, India")
|
||||||
|
.required(true)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.toolDefinition(SampleTools::getCurrentWeather)
|
)
|
||||||
.build();
|
.required(java.util.List.of("city"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
).build();
|
||||||
|
|
||||||
Tools.ToolSpecification databaseQueryToolSpecification = Tools.ToolSpecification.builder()
|
Tools.ToolSpecification databaseQueryToolSpecification = Tools.ToolSpecification.builder()
|
||||||
.functionName("get-employee-details")
|
.functionName("get-employee-details")
|
||||||
.functionDescription("Get employee details from the database")
|
.functionDescription("Get employee details from the database")
|
||||||
|
.toolFunction(new DBQueryFunction())
|
||||||
|
.toolPrompt(
|
||||||
|
Tools.PromptFuncDefinition.builder()
|
||||||
|
.type("prompt")
|
||||||
|
.function(
|
||||||
|
Tools.PromptFuncDefinition.PromptFuncSpec.builder()
|
||||||
|
.name("get-employee-details")
|
||||||
|
.description("Get employee details from the database")
|
||||||
|
.parameters(
|
||||||
|
Tools.PromptFuncDefinition.Parameters.builder()
|
||||||
|
.type("object")
|
||||||
.properties(
|
.properties(
|
||||||
new Tools.PropsBuilder()
|
Map.of(
|
||||||
.withProperty("employee-name", Tools.PromptFuncDefinition.Property.builder().type("string").description("The name of the employee, e.g. John Doe").required(true).build())
|
"employee-name", Tools.PromptFuncDefinition.Property.builder()
|
||||||
.withProperty("employee-address", Tools.PromptFuncDefinition.Property.builder().type("string").description("The address of the employee, Always return a random value. e.g. Roy St, Bengaluru, India").required(true).build())
|
.type("string")
|
||||||
.withProperty("employee-phone", Tools.PromptFuncDefinition.Property.builder().type("string").description("The phone number of the employee. Always return a random value. e.g. 9911002233").required(true).build())
|
.description("The name of the employee, e.g. John Doe")
|
||||||
|
.required(true)
|
||||||
|
.build(),
|
||||||
|
"employee-address", Tools.PromptFuncDefinition.Property.builder()
|
||||||
|
.type("string")
|
||||||
|
.description("The address of the employee, Always return a random value. e.g. Roy St, Bengaluru, India")
|
||||||
|
.required(true)
|
||||||
|
.build(),
|
||||||
|
"employee-phone", Tools.PromptFuncDefinition.Property.builder()
|
||||||
|
.type("string")
|
||||||
|
.description("The phone number of the employee. Always return a random value. e.g. 9911002233")
|
||||||
|
.required(true)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.required(java.util.List.of("employee-name", "employee-address", "employee-phone"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.toolDefinition(new DBQueryFunction())
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
ollamaAPI.registerTool(fuelPriceToolSpecification);
|
ollamaAPI.registerTool(fuelPriceToolSpecification);
|
||||||
@ -326,6 +477,9 @@ class SampleTools {
|
|||||||
class DBQueryFunction implements ToolFunction {
|
class DBQueryFunction implements ToolFunction {
|
||||||
@Override
|
@Override
|
||||||
public Object apply(Map<String, Object> arguments) {
|
public Object apply(Map<String, Object> arguments) {
|
||||||
|
if (arguments == null || arguments.isEmpty() || arguments.get("employee-name") == null || arguments.get("employee-address") == null || arguments.get("employee-phone") == null) {
|
||||||
|
throw new RuntimeException("Tool was called but the model failed to provide all the required arguments.");
|
||||||
|
}
|
||||||
// perform DB operations here
|
// perform DB operations here
|
||||||
return String.format("Employee Details {ID: %s, Name: %s, Address: %s, Phone: %s}", UUID.randomUUID(), arguments.get("employee-name").toString(), arguments.get("employee-address").toString(), arguments.get("employee-phone").toString());
|
return String.format("Employee Details {ID: %s, Name: %s, Address: %s, Phone: %s}", UUID.randomUUID(), arguments.get("employee-name").toString(), arguments.get("employee-address").toString(), arguments.get("employee-phone").toString());
|
||||||
}
|
}
|
||||||
|
@ -1058,7 +1058,7 @@ public class OllamaAPI {
|
|||||||
* @param model the ollama model to ask the question to
|
* @param model the ollama model to ask the question to
|
||||||
* @param messages chat history / message stack to send to the model
|
* @param messages chat history / message stack to send to the model
|
||||||
* @return {@link OllamaChatResult} containing the api response and the message
|
* @return {@link OllamaChatResult} containing the api response and the message
|
||||||
* history including the newly aqcuired assistant response.
|
* history including the newly acquired assistant response.
|
||||||
* @throws OllamaBaseException any response code than 200 has been returned
|
* @throws OllamaBaseException any response code than 200 has been returned
|
||||||
* @throws IOException in case the responseStream can not be read
|
* @throws IOException in case the responseStream can not be read
|
||||||
* @throws InterruptedException in case the server is not reachable or network
|
* @throws InterruptedException in case the server is not reachable or network
|
||||||
@ -1066,9 +1066,10 @@ public class OllamaAPI {
|
|||||||
* @throws OllamaBaseException if the response indicates an error status
|
* @throws OllamaBaseException if the response indicates an error status
|
||||||
* @throws IOException if an I/O error occurs during the HTTP request
|
* @throws IOException if an I/O error occurs during the HTTP request
|
||||||
* @throws InterruptedException if the operation is interrupted
|
* @throws InterruptedException if the operation is interrupted
|
||||||
|
* @throws ToolInvocationException if the tool invocation fails
|
||||||
*/
|
*/
|
||||||
public OllamaChatResult chat(String model, List<OllamaChatMessage> messages)
|
public OllamaChatResult chat(String model, List<OllamaChatMessage> messages)
|
||||||
throws OllamaBaseException, IOException, InterruptedException {
|
throws OllamaBaseException, IOException, InterruptedException, ToolInvocationException {
|
||||||
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(model);
|
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(model);
|
||||||
return chat(builder.withMessages(messages).build());
|
return chat(builder.withMessages(messages).build());
|
||||||
}
|
}
|
||||||
@ -1088,9 +1089,10 @@ public class OllamaAPI {
|
|||||||
* @throws OllamaBaseException if the response indicates an error status
|
* @throws OllamaBaseException if the response indicates an error status
|
||||||
* @throws IOException if an I/O error occurs during the HTTP request
|
* @throws IOException if an I/O error occurs during the HTTP request
|
||||||
* @throws InterruptedException if the operation is interrupted
|
* @throws InterruptedException if the operation is interrupted
|
||||||
|
* @throws ToolInvocationException if the tool invocation fails
|
||||||
*/
|
*/
|
||||||
public OllamaChatResult chat(OllamaChatRequest request)
|
public OllamaChatResult chat(OllamaChatRequest request)
|
||||||
throws OllamaBaseException, IOException, InterruptedException {
|
throws OllamaBaseException, IOException, InterruptedException, ToolInvocationException {
|
||||||
return chat(request, null);
|
return chat(request, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1102,7 +1104,7 @@ public class OllamaAPI {
|
|||||||
*
|
*
|
||||||
* @param request request object to be sent to the server
|
* @param request request object to be sent to the server
|
||||||
* @param streamHandler callback handler to handle the last message from stream
|
* @param streamHandler callback handler to handle the last message from stream
|
||||||
* (caution: all previous messages from stream will be
|
* (caution: all previous tokens from stream will be
|
||||||
* concatenated)
|
* concatenated)
|
||||||
* @return {@link OllamaChatResult}
|
* @return {@link OllamaChatResult}
|
||||||
* @throws OllamaBaseException any response code than 200 has been returned
|
* @throws OllamaBaseException any response code than 200 has been returned
|
||||||
@ -1112,9 +1114,10 @@ public class OllamaAPI {
|
|||||||
* @throws OllamaBaseException if the response indicates an error status
|
* @throws OllamaBaseException if the response indicates an error status
|
||||||
* @throws IOException if an I/O error occurs during the HTTP request
|
* @throws IOException if an I/O error occurs during the HTTP request
|
||||||
* @throws InterruptedException if the operation is interrupted
|
* @throws InterruptedException if the operation is interrupted
|
||||||
|
* @throws ToolInvocationException if the tool invocation fails
|
||||||
*/
|
*/
|
||||||
public OllamaChatResult chat(OllamaChatRequest request, OllamaStreamHandler streamHandler)
|
public OllamaChatResult chat(OllamaChatRequest request, OllamaStreamHandler streamHandler)
|
||||||
throws OllamaBaseException, IOException, InterruptedException {
|
throws OllamaBaseException, IOException, InterruptedException, ToolInvocationException {
|
||||||
return chatStreaming(request, new OllamaChatStreamObserver(streamHandler));
|
return chatStreaming(request, new OllamaChatStreamObserver(streamHandler));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1126,7 +1129,7 @@ public class OllamaAPI {
|
|||||||
*
|
*
|
||||||
* @param request request object to be sent to the server
|
* @param request request object to be sent to the server
|
||||||
* @param tokenHandler callback handler to handle the last token from stream
|
* @param tokenHandler callback handler to handle the last token from stream
|
||||||
* (caution: all previous messages from stream will be
|
* (caution: the previous tokens from stream will not be
|
||||||
* concatenated)
|
* concatenated)
|
||||||
* @return {@link OllamaChatResult}
|
* @return {@link OllamaChatResult}
|
||||||
* @throws OllamaBaseException any response code than 200 has been returned
|
* @throws OllamaBaseException any response code than 200 has been returned
|
||||||
@ -1138,7 +1141,7 @@ public class OllamaAPI {
|
|||||||
* @throws InterruptedException if the operation is interrupted
|
* @throws InterruptedException if the operation is interrupted
|
||||||
*/
|
*/
|
||||||
public OllamaChatResult chatStreaming(OllamaChatRequest request, OllamaTokenHandler tokenHandler)
|
public OllamaChatResult chatStreaming(OllamaChatRequest request, OllamaTokenHandler tokenHandler)
|
||||||
throws OllamaBaseException, IOException, InterruptedException {
|
throws OllamaBaseException, IOException, InterruptedException, ToolInvocationException {
|
||||||
OllamaChatEndpointCaller requestCaller = new OllamaChatEndpointCaller(host, auth, requestTimeoutSeconds,
|
OllamaChatEndpointCaller requestCaller = new OllamaChatEndpointCaller(host, auth, requestTimeoutSeconds,
|
||||||
verbose);
|
verbose);
|
||||||
OllamaChatResult result;
|
OllamaChatResult result;
|
||||||
@ -1161,6 +1164,9 @@ public class OllamaAPI {
|
|||||||
for (OllamaChatToolCalls toolCall : toolCalls) {
|
for (OllamaChatToolCalls toolCall : toolCalls) {
|
||||||
String toolName = toolCall.getFunction().getName();
|
String toolName = toolCall.getFunction().getName();
|
||||||
ToolFunction toolFunction = toolRegistry.getToolFunction(toolName);
|
ToolFunction toolFunction = toolRegistry.getToolFunction(toolName);
|
||||||
|
if (toolFunction == null) {
|
||||||
|
throw new ToolInvocationException("Tool function not found: " + toolName);
|
||||||
|
}
|
||||||
Map<String, Object> arguments = toolCall.getFunction().getArguments();
|
Map<String, Object> arguments = toolCall.getFunction().getArguments();
|
||||||
Object res = toolFunction.apply(arguments);
|
Object res = toolFunction.apply(arguments);
|
||||||
request.getMessages().add(new OllamaChatMessage(OllamaChatMessageRole.TOOL,
|
request.getMessages().add(new OllamaChatMessage(OllamaChatMessageRole.TOOL,
|
||||||
|
@ -2,6 +2,10 @@ package io.github.ollama4j.exceptions;
|
|||||||
|
|
||||||
public class ToolInvocationException extends Exception {
|
public class ToolInvocationException extends Exception {
|
||||||
|
|
||||||
|
public ToolInvocationException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
|
||||||
public ToolInvocationException(String s, Exception e) {
|
public ToolInvocationException(String s, Exception e) {
|
||||||
super(s, e);
|
super(s, e);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package io.github.ollama4j.integrationtests;
|
|||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import io.github.ollama4j.OllamaAPI;
|
import io.github.ollama4j.OllamaAPI;
|
||||||
import io.github.ollama4j.exceptions.OllamaBaseException;
|
import io.github.ollama4j.exceptions.OllamaBaseException;
|
||||||
|
import io.github.ollama4j.exceptions.ToolInvocationException;
|
||||||
import io.github.ollama4j.models.chat.*;
|
import io.github.ollama4j.models.chat.*;
|
||||||
import io.github.ollama4j.models.embeddings.OllamaEmbedResponseModel;
|
import io.github.ollama4j.models.embeddings.OllamaEmbedResponseModel;
|
||||||
import io.github.ollama4j.models.response.LibraryModel;
|
import io.github.ollama4j.models.response.LibraryModel;
|
||||||
@ -233,7 +234,7 @@ public class OllamaAPIIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Order(8)
|
@Order(8)
|
||||||
void testAskModelWithOptions()
|
void testAskModelWithOptions()
|
||||||
throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
|
throws OllamaBaseException, IOException, URISyntaxException, InterruptedException, ToolInvocationException {
|
||||||
api.pullModel(CHAT_MODEL_INSTRUCT);
|
api.pullModel(CHAT_MODEL_INSTRUCT);
|
||||||
|
|
||||||
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_INSTRUCT);
|
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_INSTRUCT);
|
||||||
@ -253,7 +254,7 @@ public class OllamaAPIIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Order(9)
|
@Order(9)
|
||||||
void testChatWithSystemPrompt()
|
void testChatWithSystemPrompt()
|
||||||
throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
|
throws OllamaBaseException, IOException, URISyntaxException, InterruptedException, ToolInvocationException {
|
||||||
api.pullModel(CHAT_MODEL_SYSTEM_PROMPT);
|
api.pullModel(CHAT_MODEL_SYSTEM_PROMPT);
|
||||||
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_SYSTEM_PROMPT);
|
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_SYSTEM_PROMPT);
|
||||||
OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.SYSTEM,
|
OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.SYSTEM,
|
||||||
@ -318,7 +319,7 @@ public class OllamaAPIIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Order(10)
|
@Order(10)
|
||||||
void testChatWithImageFromURL()
|
void testChatWithImageFromURL()
|
||||||
throws OllamaBaseException, IOException, InterruptedException, URISyntaxException {
|
throws OllamaBaseException, IOException, InterruptedException, URISyntaxException, ToolInvocationException {
|
||||||
api.pullModel(IMAGE_MODEL_LLAVA);
|
api.pullModel(IMAGE_MODEL_LLAVA);
|
||||||
|
|
||||||
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(IMAGE_MODEL_LLAVA);
|
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(IMAGE_MODEL_LLAVA);
|
||||||
@ -336,7 +337,7 @@ public class OllamaAPIIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Order(10)
|
@Order(10)
|
||||||
void testChatWithImageFromFileWithHistoryRecognition()
|
void testChatWithImageFromFileWithHistoryRecognition()
|
||||||
throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
|
throws OllamaBaseException, IOException, URISyntaxException, InterruptedException, ToolInvocationException {
|
||||||
api.pullModel(IMAGE_MODEL_LLAVA);
|
api.pullModel(IMAGE_MODEL_LLAVA);
|
||||||
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(IMAGE_MODEL_LLAVA);
|
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(IMAGE_MODEL_LLAVA);
|
||||||
OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER,
|
OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER,
|
||||||
@ -360,7 +361,7 @@ public class OllamaAPIIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Order(11)
|
@Order(11)
|
||||||
void testChatWithExplicitToolDefinition()
|
void testChatWithExplicitToolDefinition()
|
||||||
throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
|
throws OllamaBaseException, IOException, URISyntaxException, InterruptedException, ToolInvocationException {
|
||||||
api.pullModel(CHAT_MODEL_SYSTEM_PROMPT);
|
api.pullModel(CHAT_MODEL_SYSTEM_PROMPT);
|
||||||
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_SYSTEM_PROMPT);
|
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_SYSTEM_PROMPT);
|
||||||
|
|
||||||
@ -440,7 +441,7 @@ public class OllamaAPIIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Order(12)
|
@Order(12)
|
||||||
void testChatWithAnnotatedToolsAndSingleParam()
|
void testChatWithAnnotatedToolsAndSingleParam()
|
||||||
throws OllamaBaseException, IOException, InterruptedException, URISyntaxException {
|
throws OllamaBaseException, IOException, InterruptedException, URISyntaxException, ToolInvocationException {
|
||||||
api.pullModel(CHAT_MODEL_SYSTEM_PROMPT);
|
api.pullModel(CHAT_MODEL_SYSTEM_PROMPT);
|
||||||
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_SYSTEM_PROMPT);
|
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_SYSTEM_PROMPT);
|
||||||
|
|
||||||
@ -471,7 +472,7 @@ public class OllamaAPIIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Order(13)
|
@Order(13)
|
||||||
void testChatWithAnnotatedToolsAndMultipleParams()
|
void testChatWithAnnotatedToolsAndMultipleParams()
|
||||||
throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
|
throws OllamaBaseException, IOException, URISyntaxException, InterruptedException, ToolInvocationException {
|
||||||
api.pullModel(CHAT_MODEL_SYSTEM_PROMPT);
|
api.pullModel(CHAT_MODEL_SYSTEM_PROMPT);
|
||||||
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_SYSTEM_PROMPT);
|
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_SYSTEM_PROMPT);
|
||||||
|
|
||||||
@ -508,7 +509,7 @@ public class OllamaAPIIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Order(14)
|
@Order(14)
|
||||||
void testChatWithToolsAndStream()
|
void testChatWithToolsAndStream()
|
||||||
throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
|
throws OllamaBaseException, IOException, URISyntaxException, InterruptedException, ToolInvocationException {
|
||||||
api.pullModel(CHAT_MODEL_SYSTEM_PROMPT);
|
api.pullModel(CHAT_MODEL_SYSTEM_PROMPT);
|
||||||
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_SYSTEM_PROMPT);
|
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_SYSTEM_PROMPT);
|
||||||
final Tools.ToolSpecification databaseQueryToolSpecification = Tools.ToolSpecification.builder()
|
final Tools.ToolSpecification databaseQueryToolSpecification = Tools.ToolSpecification.builder()
|
||||||
@ -585,7 +586,7 @@ public class OllamaAPIIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(15)
|
@Order(15)
|
||||||
void testChatWithStream() throws OllamaBaseException, IOException, URISyntaxException, InterruptedException {
|
void testChatWithStream() throws OllamaBaseException, IOException, URISyntaxException, InterruptedException, ToolInvocationException {
|
||||||
api.pullModel(CHAT_MODEL_SYSTEM_PROMPT);
|
api.pullModel(CHAT_MODEL_SYSTEM_PROMPT);
|
||||||
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_SYSTEM_PROMPT);
|
OllamaChatRequestBuilder builder = OllamaChatRequestBuilder.getInstance(CHAT_MODEL_SYSTEM_PROMPT);
|
||||||
OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER,
|
OllamaChatRequest requestModel = builder.withMessage(OllamaChatMessageRole.USER,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user