CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-springframework-ai--spring-ai-model

Core model interfaces and abstractions for Spring AI framework providing portable API for chat, embeddings, images, audio, and tool calling across multiple AI providers

Overview
Eval results
Files

tool-calling-options.mddocs/reference/

Tool Calling Chat Options

Advanced chat options for configuring tool/function calling behavior, including tool registration, execution control, and context management.

Capabilities

ToolCallingChatOptions Interface

Extended chat options interface specifically for tool calling functionality.

public interface ToolCallingChatOptions extends ChatOptions {
    /**
     * Default value for tool execution enabled flag.
     */
    boolean DEFAULT_TOOL_EXECUTION_ENABLED = true;

    /**
     * Get the tool callbacks registered with the chat model.
     *
     * @return list of tool callbacks
     */
    List<ToolCallback> getToolCallbacks();

    /**
     * Set the tool callbacks to be registered with the chat model.
     *
     * @param toolCallbacks the list of tool callbacks
     */
    void setToolCallbacks(List<ToolCallback> toolCallbacks);

    /**
     * Get the names of the tools to register with the chat model.
     *
     * @return set of tool names
     */
    Set<String> getToolNames();

    /**
     * Set the names of the tools to register with the chat model.
     *
     * @param toolNames the set of tool names
     */
    void setToolNames(Set<String> toolNames);

    /**
     * Whether the ChatModel is responsible for executing tools requested by the model,
     * or if tools should be executed directly by the caller.
     *
     * @return true if internal tool execution is enabled, false if manual execution, null for default
     */
    @Nullable
    Boolean getInternalToolExecutionEnabled();

    /**
     * Set whether the ChatModel is responsible for executing the tools.
     *
     * @param internalToolExecutionEnabled true for internal execution, false for manual
     */
    void setInternalToolExecutionEnabled(@Nullable Boolean internalToolExecutionEnabled);

    /**
     * Get the configured tool context.
     *
     * @return the tool context map
     */
    Map<String, Object> getToolContext();

    /**
     * Set the tool context values as map.
     *
     * @param toolContext the tool context map
     */
    void setToolContext(Map<String, Object> toolContext);

    /**
     * Create a new builder for ToolCallingChatOptions.
     *
     * @return a new builder
     */
    static Builder builder();

    /**
     * Check if internal tool execution is enabled for the given chat options.
     *
     * @param chatOptions the chat options to check
     * @return true if internal execution is enabled
     */
    static boolean isInternalToolExecutionEnabled(ChatOptions chatOptions);

    /**
     * Merge runtime and default tool names.
     *
     * @param runtimeToolNames the runtime tool names
     * @param defaultToolNames the default tool names
     * @return merged set of tool names
     */
    static Set<String> mergeToolNames(Set<String> runtimeToolNames, Set<String> defaultToolNames);

    /**
     * Merge runtime and default tool callbacks.
     *
     * @param runtimeToolCallbacks the runtime tool callbacks
     * @param defaultToolCallbacks the default tool callbacks
     * @return merged list of tool callbacks
     */
    static List<ToolCallback> mergeToolCallbacks(
        List<ToolCallback> runtimeToolCallbacks,
        List<ToolCallback> defaultToolCallbacks
    );

    /**
     * Merge runtime and default tool context.
     *
     * @param runtimeToolContext the runtime tool context
     * @param defaultToolContext the default tool context
     * @return merged tool context map
     */
    static Map<String, Object> mergeToolContext(
        Map<String, Object> runtimeToolContext,
        Map<String, Object> defaultToolContext
    );

    /**
     * Validate that tool callbacks don't have duplicate names.
     *
     * @param toolCallbacks the tool callbacks to validate
     * @throws IllegalStateException if duplicate tool names found
     */
    static void validateToolCallbacks(List<ToolCallback> toolCallbacks);
}

ToolCallingChatOptions.Builder Interface

Builder interface for constructing ToolCallingChatOptions instances.

interface Builder extends ChatOptions.Builder {
    /**
     * Set tool callbacks to be registered with the ChatModel.
     *
     * @param toolCallbacks the list of tool callbacks
     * @return this builder
     */
    Builder toolCallbacks(List<ToolCallback> toolCallbacks);

    /**
     * Set tool callbacks to be registered with the ChatModel.
     *
     * @param toolCallbacks varargs of tool callbacks
     * @return this builder
     */
    Builder toolCallbacks(ToolCallback... toolCallbacks);

    /**
     * Set names of the tools to register with the ChatModel.
     *
     * @param toolNames the set of tool names
     * @return this builder
     */
    Builder toolNames(Set<String> toolNames);

    /**
     * Set names of the tools to register with the ChatModel.
     *
     * @param toolNames varargs of tool names
     * @return this builder
     */
    Builder toolNames(String... toolNames);

    /**
     * Set whether the ChatModel is responsible for executing the tools.
     *
     * @param internalToolExecutionEnabled true for internal execution
     * @return this builder
     */
    Builder internalToolExecutionEnabled(@Nullable Boolean internalToolExecutionEnabled);

    /**
     * Add a Map of context values into tool context.
     *
     * @param context the map representing the tool context
     * @return this builder
     */
    Builder toolContext(Map<String, Object> context);

    /**
     * Add a specific key/value pair to the tool context.
     *
     * @param key the key to use
     * @param value the corresponding value
     * @return this builder
     */
    Builder toolContext(String key, Object value);

    // ChatOptions.Builder methods

    @Override
    Builder model(@Nullable String model);

    @Override
    Builder frequencyPenalty(@Nullable Double frequencyPenalty);

    @Override
    Builder maxTokens(@Nullable Integer maxTokens);

    @Override
    Builder presencePenalty(@Nullable Double presencePenalty);

    @Override
    Builder stopSequences(@Nullable List<String> stopSequences);

    @Override
    Builder temperature(@Nullable Double temperature);

    @Override
    Builder topK(@Nullable Integer topK);

    @Override
    Builder topP(@Nullable Double topP);

    @Override
    ToolCallingChatOptions build();
}

StructuredOutputChatOptions Interface

Mixin interface for ChatModels that support structured output with JSON schema.

public interface StructuredOutputChatOptions extends ChatOptions {
    /**
     * Get the output JSON schema.
     *
     * @return the JSON schema string
     */
    String getOutputSchema();

    /**
     * Set the output JSON schema for structured responses.
     *
     * @param outputSchema the JSON schema string
     */
    void setOutputSchema(String outputSchema);
}

DefaultToolCallingChatOptions

Default implementation of ToolCallingChatOptions.

public class DefaultToolCallingChatOptions implements ToolCallingChatOptions {
    // Implementation of all ToolCallingChatOptions and ChatOptions methods
    // with getters and setters for tool callbacks, tool names, tool context,
    // internal tool execution flag, and all standard chat options
}

ToolContext

Represents the context for tool execution in function calling scenarios.

public final class ToolContext {
    /**
     * Key for the tool call history stored in the context map.
     */
    public static final String TOOL_CALL_HISTORY = "TOOL_CALL_HISTORY";

    /**
     * Constructs a new ToolContext with the given context map.
     *
     * @param context A map containing the tool context information (made unmodifiable)
     */
    public ToolContext(Map<String, Object> context);

    /**
     * Returns the immutable context map.
     *
     * @return An unmodifiable view of the context map
     */
    public Map<String, Object> getContext();

    /**
     * Returns the tool call history from the context map.
     *
     * @return The tool call history
     */
    public List<Message> getToolCallHistory();
}

Tool Calling Management

ToolCallingManager Interface

Service responsible for managing the tool calling process for a chat model.

public interface ToolCallingManager {
    /**
     * Resolve the tool definitions from the model's tool calling options.
     *
     * @param chatOptions the tool calling chat options
     * @return list of resolved tool definitions
     */
    List<ToolDefinition> resolveToolDefinitions(ToolCallingChatOptions chatOptions);

    /**
     * Execute the tool calls requested by the model.
     *
     * @param prompt the original prompt
     * @param chatResponse the chat response containing tool calls
     * @return the tool execution result
     */
    ToolExecutionResult executeToolCalls(Prompt prompt, ChatResponse chatResponse);

    /**
     * Create a default ToolCallingManager builder.
     *
     * @return a new builder
     */
    static DefaultToolCallingManager.Builder builder();
}

DefaultToolCallingManager

Default implementation of ToolCallingManager.

public final class DefaultToolCallingManager implements ToolCallingManager {
    /**
     * Construct a DefaultToolCallingManager with required dependencies.
     *
     * @param observationRegistry the observation registry for metrics
     * @param toolCallbackResolver the resolver for tool callbacks
     * @param toolExecutionExceptionProcessor the processor for tool exceptions
     */
    public DefaultToolCallingManager(
        ObservationRegistry observationRegistry,
        ToolCallbackResolver toolCallbackResolver,
        ToolExecutionExceptionProcessor toolExecutionExceptionProcessor
    );

    @Override
    public List<ToolDefinition> resolveToolDefinitions(ToolCallingChatOptions chatOptions);

    @Override
    public ToolExecutionResult executeToolCalls(Prompt prompt, ChatResponse chatResponse);

    /**
     * Create a new builder.
     *
     * @return a new builder
     */
    public static Builder builder();

    /**
     * Builder for DefaultToolCallingManager.
     */
    public static final class Builder {
        /**
         * Set the observation registry.
         *
         * @param observationRegistry the observation registry
         * @return this builder
         */
        public Builder observationRegistry(ObservationRegistry observationRegistry);

        /**
         * Set the tool callback resolver.
         *
         * @param toolCallbackResolver the resolver
         * @return this builder
         */
        public Builder toolCallbackResolver(ToolCallbackResolver toolCallbackResolver);

        /**
         * Set the tool execution exception processor.
         *
         * @param processor the processor
         * @return this builder
         */
        public Builder toolExecutionExceptionProcessor(ToolExecutionExceptionProcessor processor);

        /**
         * Build the DefaultToolCallingManager.
         *
         * @return the manager
         */
        public DefaultToolCallingManager build();
    }
}

ToolExecutionResult Interface

The result of a tool execution, containing conversation history and execution metadata.

public interface ToolExecutionResult {
    /**
     * Finish reason constant for direct return tools.
     * When a tool is marked with returnDirect=true, this finish reason is used.
     */
    String FINISH_REASON = "returnDirect";

    /**
     * Metadata key for tool ID.
     * Used to store the unique identifier of the executed tool in message metadata.
     */
    String METADATA_TOOL_ID = "toolId";

    /**
     * Metadata key for tool name.
     * Used to store the name of the executed tool in message metadata.
     */
    String METADATA_TOOL_NAME = "toolName";

    /**
     * Get the history of messages exchanged during the conversation,
     * including the tool execution result.
     * This includes the original assistant message with tool calls and the tool response messages.
     *
     * @return the conversation history with tool calls and responses
     */
    List<Message> conversationHistory();

    /**
     * Check whether the tool execution result should be returned directly
     * or passed back to the model for further processing.
     * Returns true when any executed tool has returnDirect=true.
     *
     * @return true if result should be returned directly to the user
     */
    default boolean returnDirect() {
        return false;
    }

    /**
     * Check if the execution result contains any tool calls that need processing.
     * This is useful for determining if another model call is needed.
     *
     * @return true if there are tool calls in the conversation history
     */
    default boolean hasToolCalls() {
        return conversationHistory().stream()
            .filter(msg -> msg instanceof AssistantMessage)
            .map(msg -> (AssistantMessage) msg)
            .anyMatch(AssistantMessage::hasToolCalls);
    }

    /**
     * Create a default ToolExecutionResult builder.
     *
     * @return a new builder for constructing ToolExecutionResult instances
     */
    static DefaultToolExecutionResult.Builder builder() {
        return DefaultToolExecutionResult.builder();
    }

    /**
     * Build a list of Generation from the tool execution result,
     * useful for sending the tool execution result to the client directly.
     * This is typically used when returnDirect is true.
     *
     * @param toolExecutionResult the tool execution result to convert
     * @return list of generations representing the tool execution results
     */
    static List<Generation> buildGenerations(ToolExecutionResult toolExecutionResult) {
        return toolExecutionResult.conversationHistory().stream()
            .filter(msg -> msg instanceof ToolResponseMessage)
            .map(msg -> (ToolResponseMessage) msg)
            .flatMap(msg -> msg.getResponses().stream())
            .map(response -> new Generation(
                new AssistantMessage(response.responseData()),
                ChatGenerationMetadata.builder()
                    .finishReason(FINISH_REASON)
                    .metadata(METADATA_TOOL_ID, response.id())
                    .metadata(METADATA_TOOL_NAME, response.name())
                    .build()
            ))
            .toList();
    }
}

ToolExecutionEligibilityPredicate Interface

Predicate for determining whether a tool call is eligible for execution.

public interface ToolExecutionEligibilityPredicate {
    /**
     * Test whether a tool call should be executed.
     * This allows filtering of tool calls based on custom criteria such as
     * security policies, rate limiting, or conditional execution logic.
     *
     * @param toolCall the tool call to test
     * @param toolContext the execution context
     * @return true if the tool call should be executed
     */
    boolean test(AssistantMessage.ToolCall toolCall, ToolContext toolContext);
}

DefaultToolExecutionEligibilityPredicate

Default implementation that allows all tool calls to execute.

public class DefaultToolExecutionEligibilityPredicate implements ToolExecutionEligibilityPredicate {
    /**
     * Default implementation that returns true for all tool calls.
     *
     * @param toolCall the tool call to test
     * @param toolContext the execution context
     * @return always returns true
     */
    @Override
    public boolean test(AssistantMessage.ToolCall toolCall, ToolContext toolContext) {
        return true;
    }
}

DefaultToolExecutionResult

Record implementation of ToolExecutionResult.

public record DefaultToolExecutionResult(
    List<Message> conversationHistory,
    boolean returnDirect
) implements ToolExecutionResult {

    /**
     * Create a new builder.
     *
     * @return a new builder
     */
    public static Builder builder();

    /**
     * Builder for DefaultToolExecutionResult.
     */
    public static final class Builder {
        /**
         * Set the conversation history.
         *
         * @param conversationHistory the conversation history
         * @return this builder
         */
        public Builder conversationHistory(List<Message> conversationHistory);

        /**
         * Set whether to return directly.
         *
         * @param returnDirect true to return directly
         * @return this builder
         */
        public Builder returnDirect(boolean returnDirect);

        /**
         * Build the DefaultToolExecutionResult.
         *
         * @return the result
         */
        public DefaultToolExecutionResult build();
    }
}

Usage Examples

Basic Tool Calling Configuration

import org.springframework.ai.model.tool.ToolCallingChatOptions;
import org.springframework.ai.tool.ToolCallback;

// Build tool calling options
ToolCallingChatOptions options = ToolCallingChatOptions.builder()
    .toolCallbacks(weatherTool, calculatorTool)
    .internalToolExecutionEnabled(true)  // ChatModel executes tools automatically
    .temperature(0.7)
    .maxTokens(1000)
    .build();

// Use with prompt
Prompt prompt = new Prompt("What's the weather in London?", options);
ChatResponse response = chatModel.call(prompt);

Manual vs Internal Tool Execution

// Internal execution (default) - ChatModel handles tool calls automatically
ToolCallingChatOptions autoExecute = ToolCallingChatOptions.builder()
    .toolCallbacks(tools)
    .internalToolExecutionEnabled(true)  // or null for default
    .build();

// Manual execution - you handle tool calls yourself
ToolCallingChatOptions manualExecute = ToolCallingChatOptions.builder()
    .toolCallbacks(tools)
    .internalToolExecutionEnabled(false)  // Disable automatic execution
    .build();

Prompt prompt = new Prompt("Execute calculation", manualExecute);
ChatResponse response = chatModel.call(prompt);

// With manual execution, you need to check for tool calls and execute them
if (response.getResult().getOutput().hasToolCalls()) {
    // Handle tool calls manually
    for (AssistantMessage.ToolCall toolCall : response.getResult().getOutput().getToolCalls()) {
        // Resolve and execute tool
        ToolCallback tool = resolver.resolve(toolCall.name());
        String result = tool.call(toolCall.arguments());
        // Send result back to model...
    }
}

Tool Names Configuration

// Register specific tools by name
ToolCallingChatOptions options = ToolCallingChatOptions.builder()
    .toolNames("getCurrentWeather", "searchDatabase", "sendEmail")
    .internalToolExecutionEnabled(true)
    .build();

// Or as a set
Set<String> toolNames = Set.of("tool1", "tool2", "tool3");
options = ToolCallingChatOptions.builder()
    .toolNames(toolNames)
    .build();

Tool Context Usage

// Add context information for tools to access
ToolCallingChatOptions options = ToolCallingChatOptions.builder()
    .toolCallbacks(databaseTool, userTool)
    .toolContext("userId", "user_123")
    .toolContext("sessionId", "session_abc")
    .toolContext("permissions", List.of("read", "write"))
    .build();

// Or as a map
Map<String, Object> context = Map.of(
    "userId", "user_123",
    "sessionId", "session_abc",
    "tenant", "acme_corp"
);

options = ToolCallingChatOptions.builder()
    .toolCallbacks(tools)
    .toolContext(context)
    .build();

// Tools can access context during execution
public class DatabaseTool {
    @Tool(description = "Query database")
    public String queryDatabase(@ToolParam(description = "Query") String query) {
        // Context is available via ToolContext parameter in ToolCallback.call()
        return executeQuery(query);
    }
}

Merging Tool Options

// Define default options
ToolCallingChatOptions defaults = ToolCallingChatOptions.builder()
    .toolCallbacks(defaultTools)
    .toolNames("defaultTool1", "defaultTool2")
    .toolContext("env", "production")
    .temperature(0.7)
    .build();

// Runtime options
ToolCallingChatOptions runtime = ToolCallingChatOptions.builder()
    .toolCallbacks(additionalTools)  // Will replace defaults
    .toolContext("requestId", "req_123")  // Will be merged with defaults
    .temperature(0.9)  // Will override default
    .build();

// Use merge utilities
Set<String> mergedNames = ToolCallingChatOptions.mergeToolNames(
    runtime.getToolNames(),
    defaults.getToolNames()
);

List<ToolCallback> mergedCallbacks = ToolCallingChatOptions.mergeToolCallbacks(
    runtime.getToolCallbacks(),
    defaults.getToolCallbacks()
);

Map<String, Object> mergedContext = ToolCallingChatOptions.mergeToolContext(
    runtime.getToolContext(),
    defaults.getToolContext()
);

Validating Tool Callbacks

List<ToolCallback> tools = List.of(
    weatherTool,
    calculatorTool,
    databaseTool
);

// Validate no duplicate names
try {
    ToolCallingChatOptions.validateToolCallbacks(tools);
    // Safe to use
} catch (IllegalStateException e) {
    System.err.println("Duplicate tool names found: " + e.getMessage());
}

Checking Internal Execution Status

ChatOptions options = getOptionsFromSomewhere();

// Check if internal execution is enabled
boolean internalExec = ToolCallingChatOptions.isInternalToolExecutionEnabled(options);

if (internalExec) {
    System.out.println("ChatModel will execute tools automatically");
} else {
    System.out.println("You need to handle tool execution manually");
}

Complete Example with Tool Context

@Service
public class ToolCallingService {
    private final ChatModel chatModel;
    private final List<ToolCallback> tools;

    public String processWithContext(String userMessage, String userId, String sessionId) {
        // Build options with context
        ToolCallingChatOptions options = ToolCallingChatOptions.builder()
            .toolCallbacks(tools)
            .toolContext("userId", userId)
            .toolContext("sessionId", sessionId)
            .toolContext("timestamp", System.currentTimeMillis())
            .internalToolExecutionEnabled(true)
            .temperature(0.7)
            .maxTokens(2000)
            .build();

        // Create prompt
        Prompt prompt = new Prompt(userMessage, options);

        // Call model - tools will have access to context
        ChatResponse response = chatModel.call(prompt);

        return response.getResult().getOutput().getText();
    }
}

Spring Configuration

@Configuration
public class ToolCallingConfig {

    @Bean
    public ToolCallingChatOptions defaultToolOptions(List<ToolCallback> tools) {
        return ToolCallingChatOptions.builder()
            .toolCallbacks(tools)
            .internalToolExecutionEnabled(true)
            .temperature(0.7)
            .maxTokens(1500)
            .build();
    }

    @Bean
    public List<ToolCallback> availableTools(
        WeatherTool weatherTool,
        DatabaseTool databaseTool,
        EmailTool emailTool
    ) {
        return List.of(
            new MethodToolCallbackProvider(weatherTool).getToolCallbacks(),
            new MethodToolCallbackProvider(databaseTool).getToolCallbacks(),
            new MethodToolCallbackProvider(emailTool).getToolCallbacks()
        ).stream().flatMap(List::stream).toList();
    }
}

Tool Context with History

import org.springframework.ai.chat.model.ToolContext;
import org.springframework.ai.chat.messages.Message;

// Create context with tool call history
Map<String, Object> contextMap = new HashMap<>();
contextMap.put("userId", "user_123");
contextMap.put(ToolContext.TOOL_CALL_HISTORY, previousMessages);

ToolContext toolContext = new ToolContext(contextMap);

// Access context in tool execution
Map<String, Object> context = toolContext.getContext();
List<Message> history = toolContext.getToolCallHistory();

// Use in options
ToolCallingChatOptions options = ToolCallingChatOptions.builder()
    .toolCallbacks(tools)
    .toolContext(contextMap)
    .build();

Advanced Tool Configuration

@Service
public class AdvancedToolService {
    private final ChatModel chatModel;

    public ChatResponse executeWithAdvancedConfig(String message, boolean autoExecute) {
        // Scan beans for tools
        MethodToolCallbackProvider provider = new MethodToolCallbackProvider(this);
        List<ToolCallback> tools = provider.getToolCallbacks();

        // Validate tools
        ToolCallingChatOptions.validateToolCallbacks(tools);

        // Build options
        ToolCallingChatOptions options = ToolCallingChatOptions.builder()
            .toolCallbacks(tools)
            .internalToolExecutionEnabled(autoExecute)
            .toolContext("service", "advanced")
            .toolContext("timestamp", System.currentTimeMillis())
            .model("gpt-4")
            .temperature(0.8)
            .maxTokens(2000)
            .build();

        return chatModel.call(new Prompt(message, options));
    }

    @Tool(description = "Process user data")
    public String processData(@ToolParam(description = "Data to process") String data) {
        // Tool implementation with context access
        return "Processed: " + data;
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-springframework-ai--spring-ai-model

docs

index.md

tile.json