Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -129,28 +129,18 @@ public OllamaChatModel(OllamaApi ollamaApi, OllamaOptions defaultOptions,
@Nullable FunctionCallbackResolver functionCallbackResolver,
@Nullable List<FunctionCallback> toolFunctionCallbacks, ObservationRegistry observationRegistry,
ModelManagementOptions modelManagementOptions) {
super(functionCallbackResolver, defaultOptions, toolFunctionCallbacks);
Assert.notNull(ollamaApi, "ollamaApi must not be null");
Assert.notNull(defaultOptions, "defaultOptions must not be null");
Assert.notNull(observationRegistry, "observationRegistry must not be null");
Assert.notNull(modelManagementOptions, "modelManagementOptions must not be null");
this.chatApi = ollamaApi;
this.defaultOptions = defaultOptions;
this.toolCallingManager = new LegacyToolCallingManager(functionCallbackResolver, toolFunctionCallbacks);
this.observationRegistry = observationRegistry;
this.modelManager = new OllamaModelManager(this.chatApi, modelManagementOptions);
initializeModel(defaultOptions.getModel(), modelManagementOptions.pullModelStrategy());
this(ollamaApi, defaultOptions, new LegacyToolCallingManager(functionCallbackResolver, toolFunctionCallbacks),
observationRegistry, modelManagementOptions);

logger.warn("This constructor is deprecated and will be removed in the next milestone. "
+ "Please use the new constructor accepting ToolCallingManager instead.");
+ "Please use the OllamaChatModel.Builder or the new constructor accepting ToolCallingManager instead.");
}

public OllamaChatModel(OllamaApi ollamaApi, OllamaOptions defaultOptions, ToolCallingManager toolCallingManager,
ObservationRegistry observationRegistry, ModelManagementOptions modelManagementOptions) {
// We do not pass the 'defaultOptions' to the AbstractToolSupport, because it
// modifies them.
// We are not using the AbstractToolSupport class in this path, so we just pass
// empty options.
// We do not pass the 'defaultOptions' to the AbstractToolSupport,
// because it modifies them. We are using ToolCallingManager instead,
// so we just pass empty options here.
super(null, OllamaOptions.builder().build(), List.of());
Assert.notNull(ollamaApi, "ollamaApi must not be null");
Assert.notNull(defaultOptions, "defaultOptions must not be null");
Expand Down Expand Up @@ -424,6 +414,8 @@ else if (prompt.getOptions() instanceof FunctionCallingOptions functionCallingOp
throw new IllegalArgumentException("model cannot be null or empty");
}

ToolCallingChatOptions.validateToolCallbacks(requestOptions.getToolCallbacks());

return new Prompt(prompt.getInstructions(), requestOptions);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.ai.model.tool.ToolCallingChatOptions;
import org.springframework.ai.ollama.api.OllamaApi;
import org.springframework.ai.ollama.api.OllamaOptions;
Expand Down Expand Up @@ -48,7 +49,7 @@ void whenToolRuntimeOptionsThenMergeWithDefaults() {
.internalToolExecutionEnabled(true)
.toolCallbacks(new TestToolCallback("tool1"), new TestToolCallback("tool2"))
.toolNames("tool1", "tool2")
.toolContext(Map.of("key1", "value1"))
.toolContext(Map.of("key1", "value1", "key2", "valueA"))
.build();
OllamaChatModel chatModel = OllamaChatModel.builder()
.ollamaApi(new OllamaApi())
Expand All @@ -59,17 +60,19 @@ void whenToolRuntimeOptionsThenMergeWithDefaults() {
.internalToolExecutionEnabled(false)
.toolCallbacks(new TestToolCallback("tool3"), new TestToolCallback("tool4"))
.toolNames("tool3")
.toolContext(Map.of("key2", "value2"))
.toolContext(Map.of("key2", "valueB"))
.build();
Prompt prompt = chatModel.buildRequestPrompt(new Prompt("Test message content", runtimeOptions));

assertThat(((ToolCallingChatOptions) prompt.getOptions())).isNotNull();
assertThat(((ToolCallingChatOptions) prompt.getOptions()).isInternalToolExecutionEnabled()).isFalse();
assertThat(((ToolCallingChatOptions) prompt.getOptions()).getToolCallbacks()).hasSize(4);
assertThat(((ToolCallingChatOptions) prompt.getOptions()).getToolNames()).containsExactlyInAnyOrder("tool1",
"tool2", "tool3");
assertThat(((ToolCallingChatOptions) prompt.getOptions()).getToolCallbacks()).hasSize(2);
assertThat(((ToolCallingChatOptions) prompt.getOptions()).getToolCallbacks()
.stream()
.map(FunctionCallback::getName)).containsExactlyInAnyOrder("tool3", "tool4");
assertThat(((ToolCallingChatOptions) prompt.getOptions()).getToolNames()).containsExactlyInAnyOrder("tool3");
assertThat(((ToolCallingChatOptions) prompt.getOptions()).getToolContext()).containsEntry("key1", "value1")
.containsEntry("key2", "value2");
.containsEntry("key2", "valueB");
}

@Test
Expand Down
Loading