Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for registering Supplier functions in addition to Function interfaces for LLM function calling #1277

Closed
jsilverman26 opened this issue Aug 27, 2024 · 4 comments

Comments

@jsilverman26
Copy link
Contributor

Please do a quick search on GitHub issues first, the feature you are about to request might have already been requested.

Expected Behavior
I expect that Spring AI should support registering java.util.function.Supplier functions for LLM (Large Language Model) function calling, in addition to the currently supported java.util.function.Function interface. This would allow developers to register functions that do not take any arguments but return a dynamic result, such as a random number generator, the current time, or the server's health status.

Here are a few examples where Supplier functions would be useful:

  1. Random Value Generation:

    • Generate a random integer within a specified range:
      Supplier<Integer> randomNumberSupplier = () -> new Random().nextInt(100); // Generates a random number between 0 and 99
    • Generate a random UUID string:
      Supplier<String> randomStringSupplier = () -> UUID.randomUUID().toString();
  2. Time-Related Information:

    • Retrieve the current timestamp:
      Supplier<LocalDateTime> currentTimeSupplier = () -> LocalDateTime.now();
    • Retrieve the current date in a specific format:
      Supplier<String> formattedDateSupplier = () -> LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
  3. Server Status Monitoring:

    • Return the server's current health status, such as "OK" or "FAIL":
      Supplier<String> serverStatusSupplier = () -> "OK"; // In a real scenario, this would check the actual server status

By supporting Supplier functions, Spring AI would allow for more dynamic and versatile function calling capabilities in LLM-powered applications. These functions are essential for generating real-time or context-dependent data without requiring any input parameters.

Current Behavior

Currently, it appears that Spring AI only supports registering functions that implement the java.util.function.Function interface for LLM function calling. This limits the functionality to only those functions that take an input and return an output. However, there are use cases where functions that take no arguments but return a value (like Supplier) would be more appropriate. This limitation makes it impossible to implement certain types of functionality using the current version.

Context
This issue has affected our ability to fully utilize Spring AI for dynamic content generation, such as generating random numbers or strings within the context of an LLM-powered application. We have considered alternative approaches, such as wrapping a Supplier within a Function, but this feels like a workaround rather than a proper solution. We believe that direct support for Supplier would be a more elegant and useful addition to the framework.

Are there any plans to support this feature, or is there a recommended workaround that we may not be aware of?

@ullenboom
Copy link

Assuming the FunctionCallbackWrapper class has a new builder(Supplier<O> function) method, is there really much difference between writing:

FunctionCallbackWrapper.builder(() -> LocalDate.now());

and:

FunctionCallbackWrapper.builder(_ -> LocalDate.now());  // Java 22; use __ for earlier versions

Or, you could just use your simple utility method:

public static <Void, O> FunctionCallbackWrapper.Builder<Void, O> builder(Supplier<O> function) {
  return new FunctionCallbackWrapper.Builder<>(__ -> function.get());
}

@jsilverman26
Copy link
Contributor Author

jsilverman26 commented Aug 28, 2024

@ullenboom
Thank you for the detailed explanation! I understand the utility of converting a Supplier to a Function using a utility method, and it certainly works without adding new methods. However, my concern is to simplify the API for cases where Supplier would be more natural. For example, in a Spring Boot application where I need to retrieve the current time, the current implementation requires using a Function like this:

@GetMapping("/sample")
public AssistantMessage sample() {
    return chatClient.prompt()
            .function("GetCurrentTime", "Use this function to get the current time.",  ... some Function code  .... )
            .system("You are a helpful AI assistant.")
            .call()
            .chatResponse()
            .getResult()
            .getOutput();

However, if Supplier were supported directly, the code could be more concise and intuitive:

@GetMapping("/sample")
public AssistantMessage sample() {
    return chatClient.prompt()
            .function("GetCurrentTime", "Use this function to get the current time.", () -> LocalDateTime.now().toString())
            .system("You are a helpful AI bot.")
            .call()
            .chatResponse()
            .getResult()
            .getOutput();
}

Supporting Supplier directly in FunctionCallbackWrapper would make such scenarios simpler and enhance the developer experience.

Feel free to share any other thoughts or suggestions; I welcome them!

@tzolov
Copy link
Contributor

tzolov commented Nov 11, 2024

This issue is part of the more generic one #1718

tzolov added a commit to tzolov/spring-ai that referenced this issue Nov 11, 2024
- Add support for Java Consumer and Supplier functional interfaces in function callbacks
- Handle void type inputs and outputs in function callbacks
- Add test cases for void responses, Consumer callbacks, and Supplier callbacks
- Update ModelOptionsUtils to properly handle void type schemas

Resolves spring-projects#1718 and spring-projects#1277
tzolov added a commit to tzolov/spring-ai that referenced this issue Nov 12, 2024
- Add support for Java Consumer and Supplier functional interfaces in function callbacks
- Handle void type inputs and outputs in function callbacks
- Add test cases for void responses, Consumer callbacks, and Supplier callbacks
- Update ModelOptionsUtils to properly handle void type schemas

Resolves spring-projects#1718 and spring-projects#1277
tzolov added a commit to tzolov/spring-ai that referenced this issue Nov 12, 2024
- Add support for Java Consumer and Supplier functional interfaces in function callbacks
- Handle void type inputs and outputs in function callbacks
- Add test cases for void responses, Consumer callbacks, and Supplier callbacks
- Update ModelOptionsUtils to properly handle void type schemas

Resolves spring-projects#1718 and spring-projects#1277
tzolov added a commit to tzolov/spring-ai that referenced this issue Nov 12, 2024
- Add support for Java Consumer and Supplier functional interfaces in function callbacks
- Handle void type inputs and outputs in function callbacks
- Add test cases for void responses, Consumer callbacks, and Supplier callbacks
- Update ModelOptionsUtils to properly handle void type schemas

Resolves spring-projects#1718 and spring-projects#1277
tzolov added a commit to tzolov/spring-ai that referenced this issue Nov 16, 2024
Add support for no-argument Supplier and single-argument Consumer function
callbacks in the Spring AI core module. This enhancement allows:
- Registration of Supplier<O> callbacks with no input (Void) type
- Registration of Consumer<I> callbacks with no output (Void) type
- Support for Kotlin Function0 (equivalent to Java Supplier)
- Handle empty properties for Void input types in schema generation
- Enhance FunctionCallback builder to support Supplier/Consumer patterns

Additional changes:
- Add test coverage for both Supplier and Consumer callbacks in various scenarios
- Enhance TypeResolverHelper to support Consumer input type resolution
- Support lambda-style function declarations for improved ergonomics
- Add test cases for void input/output handling in OpenAI chat model
- Include examples of function calls without return values
- Add support for parameterless functions through Supplier interface

Resolves spring-projects#1718 , spring-projects#1277 , spring-projects#1118, spring-projects#860
tzolov added a commit to tzolov/spring-ai that referenced this issue Nov 17, 2024
Add support for no-argument Supplier and single-argument Consumer function
callbacks in the Spring AI core module. This enhancement allows:
- Registration of Supplier<O> callbacks with no input (Void) type
- Registration of Consumer<I> callbacks with no output (Void) type
- Support for Kotlin Function0 (equivalent to Java Supplier)
- Handle empty properties for Void input types in schema generation
- Enhance FunctionCallback builder to support Supplier/Consumer patterns

Additional changes:
- Add test coverage for both Supplier and Consumer callbacks in various scenarios
- Enhance TypeResolverHelper to support Consumer input type resolution
- Support lambda-style function declarations for improved ergonomics
- Add test cases for void input/output handling in OpenAI chat model
- Include examples of function calls without return values
- Add support for parameterless functions through Supplier interface

Resolves spring-projects#1718 , spring-projects#1277 , spring-projects#1118, spring-projects#860
markpollack pushed a commit that referenced this issue Nov 18, 2024
Add support for no-argument Supplier and single-argument Consumer function
callbacks in the Spring AI core module. This enhancement allows:
- Registration of Supplier<O> callbacks with no input (Void) type
- Registration of Consumer<I> callbacks with no output (Void) type
- Support for Kotlin Function0 (equivalent to Java Supplier)
- Handle empty properties for Void input types in schema generation
- Enhance FunctionCallback builder to support Supplier/Consumer patterns

Additional changes:
- Add test coverage for both Supplier and Consumer callbacks in various scenarios
- Enhance TypeResolverHelper to support Consumer input type resolution
- Support lambda-style function declarations for improved ergonomics
- Add test cases for void input/output handling in OpenAI chat model
- Include examples of function calls without return values
- Add support for parameterless functions through Supplier interface

Add comprehensive documentation for the FunctionCallback API:
- Overview of the interface and its key methods
- Builder pattern usage with function and method invocation approaches
- Examples for different function types (Function, BiFunction, Supplier, Consumer)
- Best practices and common pitfalls
- Schema generation and customization options

Resolves #1718 , #1277 , #1118, #860
@markpollack
Copy link
Member

markpollack commented Nov 22, 2024

This functionality was added in M4, closing. See 432954d commit

@markpollack markpollack added this to the 1.0.0-M4 milestone Nov 22, 2024
leijendary pushed a commit to leijendary/spring-ai that referenced this issue Jan 24, 2025
Add support for no-argument Supplier and single-argument Consumer function
callbacks in the Spring AI core module. This enhancement allows:
- Registration of Supplier<O> callbacks with no input (Void) type
- Registration of Consumer<I> callbacks with no output (Void) type
- Support for Kotlin Function0 (equivalent to Java Supplier)
- Handle empty properties for Void input types in schema generation
- Enhance FunctionCallback builder to support Supplier/Consumer patterns

Additional changes:
- Add test coverage for both Supplier and Consumer callbacks in various scenarios
- Enhance TypeResolverHelper to support Consumer input type resolution
- Support lambda-style function declarations for improved ergonomics
- Add test cases for void input/output handling in OpenAI chat model
- Include examples of function calls without return values
- Add support for parameterless functions through Supplier interface

Add comprehensive documentation for the FunctionCallback API:
- Overview of the interface and its key methods
- Builder pattern usage with function and method invocation approaches
- Examples for different function types (Function, BiFunction, Supplier, Consumer)
- Best practices and common pitfalls
- Schema generation and customization options

Resolves spring-projects#1718 , spring-projects#1277 , spring-projects#1118, spring-projects#860

Signed-off-by: leijendary <jonathanleijendekker@gmail.com>
leijendary pushed a commit to leijendary/spring-ai that referenced this issue Jan 24, 2025
Add support for no-argument Supplier and single-argument Consumer function
callbacks in the Spring AI core module. This enhancement allows:
- Registration of Supplier<O> callbacks with no input (Void) type
- Registration of Consumer<I> callbacks with no output (Void) type
- Support for Kotlin Function0 (equivalent to Java Supplier)
- Handle empty properties for Void input types in schema generation
- Enhance FunctionCallback builder to support Supplier/Consumer patterns

Additional changes:
- Add test coverage for both Supplier and Consumer callbacks in various scenarios
- Enhance TypeResolverHelper to support Consumer input type resolution
- Support lambda-style function declarations for improved ergonomics
- Add test cases for void input/output handling in OpenAI chat model
- Include examples of function calls without return values
- Add support for parameterless functions through Supplier interface

Add comprehensive documentation for the FunctionCallback API:
- Overview of the interface and its key methods
- Builder pattern usage with function and method invocation approaches
- Examples for different function types (Function, BiFunction, Supplier, Consumer)
- Best practices and common pitfalls
- Schema generation and customization options

Resolves spring-projects#1718 , spring-projects#1277 , spring-projects#1118, spring-projects#860

Signed-off-by: leijendary <jonathanleijendekker@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants