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

tools.mddocs/reference/

Tool and Function Calling

Complete framework for enabling AI models to invoke Java methods and functions, including tool definitions, annotations for declarative tool creation, callbacks, resolution, execution, and comprehensive error handling.

Capabilities

ToolCallback Interface

Core interface for executing tools/functions.

public interface ToolCallback {
    /**
     * Get the tool definition describing the tool's interface.
     *
     * @return the tool definition
     */
    ToolDefinition getToolDefinition();

    /**
     * Get the tool metadata with execution hints.
     *
     * @return the tool metadata
     */
    ToolMetadata getToolMetadata();

    /**
     * Execute the tool with JSON input.
     *
     * @param toolInput the JSON-encoded tool arguments
     * @return the JSON-encoded tool result
     */
    String call(String toolInput);

    /**
     * Execute the tool with JSON input and context.
     *
     * @param toolInput the JSON-encoded tool arguments
     * @param toolContext the execution context
     * @return the JSON-encoded tool result
     */
    String call(String toolInput, ToolContext toolContext);
}

ToolCallbackProvider Interface

Provider of tool callbacks for discovery.

public interface ToolCallbackProvider {
    /**
     * Get all tool callbacks provided by this provider.
     *
     * @return list of tool callbacks
     */
    List<ToolCallback> getToolCallbacks();
}

StaticToolCallbackProvider

Static provider with a fixed list of tools.

public class StaticToolCallbackProvider implements ToolCallbackProvider {
    /**
     * Construct a StaticToolCallbackProvider with tool callbacks.
     *
     * @param toolCallbacks the list of tool callbacks
     */
    public StaticToolCallbackProvider(List<ToolCallback> toolCallbacks);

    @Override
    public List<ToolCallback> getToolCallbacks();
}

Tool Annotations

@Tool Annotation

Marks a method as a tool/function callable by AI models.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Tool {
    /**
     * The tool name. Defaults to method name.
     *
     * @return the tool name
     */
    String name() default "";

    /**
     * Description of what the tool does.
     * Used by AI to understand when to call the tool.
     * Defaults to empty string if not specified.
     *
     * @return the tool description
     */
    String description() default "";

    /**
     * Whether to return the tool result directly to the user.
     * If true, bypasses further AI processing.
     *
     * @return true to return directly
     */
    boolean returnDirect() default false;

    /**
     * Custom result converter for formatting tool output.
     *
     * @return the result converter class
     */
    Class<? extends ToolCallResultConverter> resultConverter()
        default DefaultToolCallResultConverter.class;
}

@ToolParam Annotation

Annotates tool method parameters with metadata.

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface ToolParam {
    /**
     * Whether this parameter is required.
     *
     * @return true if required
     */
    boolean required() default true;

    /**
     * Description of the parameter for AI understanding.
     *
     * @return the parameter description
     */
    String description() default "";
}

Tool Definitions

ToolDefinition Interface

Defines a tool's interface contract.

public interface ToolDefinition {
    /**
     * Get the tool name.
     *
     * @return the tool name
     */
    String name();

    /**
     * Get the tool description.
     *
     * @return the tool description
     */
    String description();

    /**
     * Get the JSON schema for tool input parameters.
     *
     * @return the JSON schema string
     */
    String inputSchema();

    /**
     * Create a new tool definition builder.
     *
     * @return a new builder
     */
    static Builder builder();
}

DefaultToolDefinition

Record implementation of ToolDefinition.

public record DefaultToolDefinition(
    String name,
    String description,
    String inputSchema
) implements ToolDefinition {

    /**
     * Builder for DefaultToolDefinition.
     */
    public static class Builder {
        public Builder name(String name);
        public Builder description(String description);
        public Builder inputSchema(String inputSchema);
        public DefaultToolDefinition build();
    }
}

Tool Metadata

ToolMetadata Interface

Metadata for tool execution behavior.

public interface ToolMetadata {
    /**
     * Whether to return tool result directly without further AI processing.
     * When true, the tool result is sent directly to the user without
     * passing through the AI model for additional processing.
     *
     * @return true to return directly, false to pass through AI model
     */
    boolean returnDirect();

    /**
     * Create a new metadata builder.
     *
     * @return a new builder for constructing ToolMetadata
     */
    static Builder builder();

    /**
     * Builder for constructing ToolMetadata instances.
     */
    interface Builder {
        /**
         * Set whether to return tool result directly.
         *
         * @param returnDirect true to return directly
         * @return this builder
         */
        Builder returnDirect(boolean returnDirect);

        /**
         * Build the ToolMetadata instance.
         *
         * @return the constructed ToolMetadata
         */
        ToolMetadata build();
    }
}

DefaultToolMetadata

Record implementation of ToolMetadata.

public record DefaultToolMetadata(boolean returnDirect) implements ToolMetadata {
}

Function Tools

FunctionToolCallback

Wraps a Java function as a tool.

public class FunctionToolCallback<I, O> implements ToolCallback {
    /**
     * Construct a FunctionToolCallback wrapping a function.
     *
     * @param definition the tool definition
     * @param function the function to wrap (input -> output)
     * @param objectMapper the Jackson ObjectMapper for JSON serialization
     */
    public FunctionToolCallback(
        ToolDefinition definition,
        Function<I, O> function,
        ObjectMapper objectMapper
    );

    @Override
    public ToolDefinition getToolDefinition();

    @Override
    public ToolMetadata getToolMetadata();

    @Override
    public String call(String toolInput);

    @Override
    public String call(String toolInput, ToolContext toolContext);
}

Method Tools

MethodToolCallback

Wraps a Java method as a tool.

public class MethodToolCallback implements ToolCallback {
    /**
     * Construct a MethodToolCallback wrapping a method.
     *
     * @param bean the object instance containing the method
     * @param method the method to wrap
     * @param definition the tool definition
     * @param metadata the tool metadata
     */
    public MethodToolCallback(
        Object bean,
        Method method,
        ToolDefinition definition,
        ToolMetadata metadata
    );

    @Override
    public ToolDefinition getToolDefinition();

    @Override
    public ToolMetadata getToolMetadata();

    @Override
    public String call(String toolInput);

    @Override
    public String call(String toolInput, ToolContext toolContext);
}

MethodToolCallbackProvider

Provider that scans beans for @Tool annotated methods.

public class MethodToolCallbackProvider implements ToolCallbackProvider {
    /**
     * Construct a MethodToolCallbackProvider scanning a bean for @Tool methods.
     *
     * @param bean the bean to scan for @Tool annotations
     */
    public MethodToolCallbackProvider(Object bean);

    @Override
    public List<ToolCallback> getToolCallbacks();
}

Tool Resolution

ToolCallbackResolver Interface

Resolves tool callbacks by name.

public interface ToolCallbackResolver {
    /**
     * Resolve a tool callback by name.
     *
     * @param toolName the tool name
     * @return the tool callback, or null if not found
     */
    ToolCallback resolve(String toolName);
}

StaticToolCallbackResolver

Resolver with a static list of tools.

public class StaticToolCallbackResolver implements ToolCallbackResolver {
    /**
     * Construct a StaticToolCallbackResolver with tool callbacks.
     *
     * @param toolCallbacks the list of tool callbacks
     */
    public StaticToolCallbackResolver(List<ToolCallback> toolCallbacks);

    @Override
    public ToolCallback resolve(String toolName);
}

SpringBeanToolCallbackResolver

Resolver that finds tools in Spring ApplicationContext.

public class SpringBeanToolCallbackResolver implements ToolCallbackResolver {
    /**
     * Construct a SpringBeanToolCallbackResolver.
     *
     * @param applicationContext the Spring application context
     */
    public SpringBeanToolCallbackResolver(ApplicationContext applicationContext);

    @Override
    public ToolCallback resolve(String toolName);
}

DelegatingToolCallbackResolver

Resolver that delegates to multiple resolvers.

public class DelegatingToolCallbackResolver implements ToolCallbackResolver {
    /**
     * Construct a DelegatingToolCallbackResolver.
     *
     * @param resolvers the list of resolvers to delegate to
     */
    public DelegatingToolCallbackResolver(List<ToolCallbackResolver> resolvers);

    @Override
    public ToolCallback resolve(String toolName);
}

TypeResolverHelper

Helper for resolving types in tool definitions and parameter extraction.

public class TypeResolverHelper {
    /**
     * Resolve the actual type from a generic type parameter.
     * Useful for extracting concrete types from parameterized interfaces.
     *
     * @param type the type to resolve
     * @param contextClass the context class containing the type
     * @return the resolved type
     */
    public static Type resolveType(Type type, Class<?> contextClass);

    /**
     * Extract parameter types from a method.
     * Returns the actual parameter types considering generic type resolution.
     *
     * @param method the method to extract parameters from
     * @return array of resolved parameter types
     */
    public static Type[] getParameterTypes(Method method);

    /**
     * Check if a type is a primitive or wrapper type.
     *
     * @param type the type to check
     * @return true if the type is primitive or a wrapper
     */
    public static boolean isPrimitiveOrWrapper(Class<?> type);
}

Tool Execution

ToolCallResultConverter Interface

Converts tool results to strings.

public interface ToolCallResultConverter {
    /**
     * Convert a tool result object to string.
     *
     * @param result the result object
     * @return the string representation
     */
    String apply(Object result);
}

DefaultToolCallResultConverter

Default converter that uses JSON serialization.

public class DefaultToolCallResultConverter implements ToolCallResultConverter {
    @Override
    public String apply(Object result);
}

ToolExecutionExceptionProcessor Interface

Processes exceptions during tool execution.

public interface ToolExecutionExceptionProcessor {
    /**
     * Process an exception into a string message.
     *
     * @param throwable the exception
     * @return the error message string
     */
    String processException(Throwable throwable);
}

DefaultToolExecutionExceptionProcessor

Default processor that formats exception messages.

public class DefaultToolExecutionExceptionProcessor implements ToolExecutionExceptionProcessor {
    @Override
    public String processException(Throwable throwable);
}

ToolExecutionException

Exception thrown during tool execution.

public class ToolExecutionException extends RuntimeException {
    /**
     * Construct a ToolExecutionException with message.
     *
     * @param message the error message
     */
    public ToolExecutionException(String message);

    /**
     * Construct a ToolExecutionException with message and cause.
     *
     * @param message the error message
     * @param cause the underlying cause
     */
    public ToolExecutionException(String message, Throwable cause);
}

Tool Support Utilities

ToolDefinitions

Utility class for creating ToolDefinition instances from Java Method objects using reflection.

public final class ToolDefinitions {
    /**
     * Create a ToolDefinition builder from a Method.
     * Extracts tool name, description, and input schema from the method.
     * Analyzes @Tool and @ToolParam annotations to build the definition.
     *
     * @param method the method to create a tool definition for
     * @return a builder for the tool definition with extracted metadata
     */
    public static DefaultToolDefinition.Builder builder(Method method);

    /**
     * Create a complete ToolDefinition from a Method.
     * Convenience method that creates and builds in one step.
     * Equivalent to calling builder(method).build().
     *
     * @param method the method to create a tool definition for
     * @return the complete tool definition ready for use
     */
    public static ToolDefinition from(Method method);

    /**
     * Create a ToolDefinition from a Function with explicit schema.
     * Useful when wrapping lambda functions or method references.
     *
     * @param name the tool name
     * @param description the tool description
     * @param inputSchema the JSON schema for input parameters
     * @return the complete tool definition
     */
    public static ToolDefinition from(String name, String description, String inputSchema);

    /**
     * Create a ToolDefinition from a Function with input class.
     * Automatically generates JSON schema from the input class.
     *
     * @param name the tool name
     * @param description the tool description
     * @param inputClass the input parameter class
     * @return the complete tool definition
     */
    public static ToolDefinition from(String name, String description, Class<?> inputClass);
}

ToolUtils

General tool utilities for working with tool callbacks and definitions.

public final class ToolUtils {
    /**
     * Extract tool name from a method.
     * Uses @Tool annotation name if present, otherwise uses method name.
     *
     * @param method the method to extract name from
     * @return the tool name
     */
    public static String getToolName(Method method);

    /**
     * Extract tool description from a method.
     * Uses @Tool annotation description if present.
     *
     * @param method the method to extract description from
     * @return the tool description
     */
    public static String getToolDescription(Method method);

    /**
     * Check if a method is annotated with @Tool.
     *
     * @param method the method to check
     * @return true if the method has @Tool annotation
     */
    public static boolean isToolMethod(Method method);

    /**
     * Create a ToolCallback from a method and bean instance.
     *
     * @param bean the object instance containing the method
     * @param method the method to wrap as a tool
     * @return a ToolCallback wrapping the method
     */
    public static ToolCallback createToolCallback(Object bean, Method method);

    /**
     * Validate that a tool callback has a valid definition.
     * Checks that name, description, and schema are properly defined.
     *
     * @param toolCallback the tool callback to validate
     * @throws IllegalArgumentException if validation fails
     */
    public static void validateToolCallback(ToolCallback toolCallback);
}

Usage Examples

Defining a Tool with Annotations

import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;

@Component
public class WeatherTools {

    @Tool(description = "Get current weather for a city")
    public String getCurrentWeather(
        @ToolParam(description = "The city name") String city,
        @ToolParam(description = "Temperature unit", required = false) String unit
    ) {
        // Implementation
        return "{\"temperature\": 72, \"condition\": \"sunny\", \"city\": \"" + city + "\"}";
    }

    @Tool(description = "Get weather forecast for next N days")
    public String getWeatherForecast(
        @ToolParam(description = "The city name") String city,
        @ToolParam(description = "Number of days") int days
    ) {
        // Implementation
        return "{\"forecast\": [...]}";
    }
}

Using Tools with ChatModel

import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;

@Service
public class ToolChatService {
    private final ChatModel chatModel;
    private final WeatherTools weatherTools;

    public String chatWithTools(String userMessage) {
        // Create tool provider
        MethodToolCallbackProvider toolProvider =
            new MethodToolCallbackProvider(weatherTools);

        // Configure options with tools
        ChatOptions options = ChatOptions.builder()
            .toolCallbacks(toolProvider.getToolCallbacks())
            .build();

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

        // Call chat model - it can now use the weather tools
        ChatResponse response = chatModel.call(prompt);
        return response.getResult().getOutput().getText();
    }
}

Creating Function Tools

import org.springframework.ai.tool.function.FunctionToolCallback;
import org.springframework.ai.tool.definition.ToolDefinition;
import com.fasterxml.jackson.databind.ObjectMapper;

// Define input/output classes
record CalculatorInput(double a, double b, String operation) {}
record CalculatorOutput(double result) {}

// Create function
Function<CalculatorInput, CalculatorOutput> calculator = input -> {
    double result = switch (input.operation()) {
        case "add" -> input.a() + input.b();
        case "subtract" -> input.a() - input.b();
        case "multiply" -> input.a() * input.b();
        case "divide" -> input.a() / input.b();
        default -> throw new IllegalArgumentException("Unknown operation");
    };
    return new CalculatorOutput(result);
};

// Create tool definition
ToolDefinition definition = ToolDefinition.builder()
    .name("calculator")
    .description("Perform basic arithmetic operations")
    .inputSchema(generateJsonSchema(CalculatorInput.class))
    .build();

// Wrap as tool
FunctionToolCallback<CalculatorInput, CalculatorOutput> tool =
    new FunctionToolCallback<>(definition, calculator, new ObjectMapper());

Tool Resolution

import org.springframework.ai.tool.resolution.*;

@Configuration
public class ToolConfig {

    @Bean
    public ToolCallbackResolver toolResolver(
        ApplicationContext context,
        List<ToolCallback> staticTools
    ) {
        // Create multiple resolvers
        SpringBeanToolCallbackResolver springResolver =
            new SpringBeanToolCallbackResolver(context);

        StaticToolCallbackResolver staticResolver =
            new StaticToolCallbackResolver(staticTools);

        // Combine with delegating resolver
        return new DelegatingToolCallbackResolver(
            List.of(springResolver, staticResolver)
        );
    }
}

Direct Return Tools

@Component
public class DirectReturnTools {

    @Tool(
        description = "Get current time",
        returnDirect = true  // Return directly to user, skip AI processing
    )
    public String getCurrentTime() {
        return LocalDateTime.now().toString();
    }

    @Tool(
        description = "Get user account balance",
        returnDirect = true
    )
    public String getBalance(@ToolParam(description = "User ID") String userId) {
        // Query database
        return "{\"balance\": 1234.56, \"currency\": \"USD\"}";
    }
}

Custom Result Converter

public class CustomResultConverter implements ToolCallResultConverter {
    @Override
    public String apply(Object result) {
        if (result instanceof Map) {
            // Custom formatting for maps
            return formatAsKeyValue((Map<?, ?>) result);
        }
        // Default JSON serialization
        return new ObjectMapper().writeValueAsString(result);
    }

    private String formatAsKeyValue(Map<?, ?> map) {
        return map.entrySet().stream()
            .map(e -> e.getKey() + ": " + e.getValue())
            .collect(Collectors.joining("\n"));
    }
}

@Tool(
    description = "Get system info",
    resultConverter = CustomResultConverter.class
)
public Map<String, String> getSystemInfo() {
    return Map.of(
        "os", System.getProperty("os.name"),
        "java", System.getProperty("java.version")
    );
}

Error Handling in Tools

@Component
public class SafeTools {

    @Tool(description = "Divide two numbers")
    public String divide(
        @ToolParam(description = "Numerator") double a,
        @ToolParam(description = "Denominator") double b
    ) {
        try {
            if (b == 0) {
                throw new ToolExecutionException("Cannot divide by zero");
            }
            double result = a / b;
            return "{\"result\": " + result + "}";
        } catch (Exception e) {
            throw new ToolExecutionException("Division failed", e);
        }
    }
}

Tool with Context

@Component
public class ContextualTools {

    @Tool(description = "Process user data")
    public String processUserData(
        @ToolParam(description = "Data to process") String data
    ) {
        // Access tool context if needed
        // Context is passed via ToolContext parameter in call method
        return "{\"processed\": true}";
    }
}

// When calling manually
ToolContext context = new ToolContext(Map.of(
    "userId", "user_123",
    "sessionId", "session_456"
));

String result = tool.call(toolInput, context);

Scanning Multiple Beans

@Configuration
public class ToolScanConfig {

    @Bean
    public ToolCallbackProvider multipleToolProviders(
        WeatherTools weatherTools,
        CalculatorTools calculatorTools,
        DatabaseTools databaseTools
    ) {
        List<ToolCallback> allTools = new ArrayList<>();

        // Scan each bean
        allTools.addAll(new MethodToolCallbackProvider(weatherTools).getToolCallbacks());
        allTools.addAll(new MethodToolCallbackProvider(calculatorTools).getToolCallbacks());
        allTools.addAll(new MethodToolCallbackProvider(databaseTools).getToolCallbacks());

        return new StaticToolCallbackProvider(allTools);
    }
}

Tool Execution Flow

@Service
public class ToolExecutionService {
    private final ChatModel chatModel;
    private final ToolCallbackResolver toolResolver;

    public String executeWithTools(String userMessage) {
        // Initial call
        ChatResponse response = chatModel.call(new Prompt(userMessage));

        // Check for tool calls
        while (response.hasToolCalls()) {
            List<Message> messages = new ArrayList<>();
            messages.add(response.getResult().getOutput());

            // Execute each tool call
            for (AssistantMessage.ToolCall toolCall :
                 response.getResult().getOutput().getToolCalls()) {

                // Resolve and execute tool
                ToolCallback tool = toolResolver.resolve(toolCall.name());
                String result = tool.call(toolCall.arguments());

                // Add tool response
                messages.add(new ToolResponseMessage(List.of(
                    new ToolResponseMessage.ToolResponse(
                        toolCall.id(),
                        toolCall.name(),
                        result
                    )
                )));
            }

            // Continue conversation with tool results
            response = chatModel.call(new Prompt(messages));
        }

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

Complex Tool Example

@Component
public class DatabaseTools {

    @Tool(description = "Search products in database")
    public String searchProducts(
        @ToolParam(description = "Search query") String query,
        @ToolParam(description = "Maximum results", required = false) Integer limit,
        @ToolParam(description = "Category filter", required = false) String category
    ) {
        // Set defaults
        int maxResults = limit != null ? limit : 10;

        // Query database
        List<Product> products = productRepository.search(query, category, maxResults);

        // Convert to JSON
        return objectMapper.writeValueAsString(products);
    }

    @Tool(description = "Get product details by ID")
    public String getProduct(
        @ToolParam(description = "Product ID") String productId
    ) {
        Product product = productRepository.findById(productId)
            .orElseThrow(() -> new ToolExecutionException("Product not found"));

        return objectMapper.writeValueAsString(product);
    }
}

Install with Tessl CLI

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

docs

index.md

tile.json