Skip to content

Commit 30165fe

Browse files
committed
Advancing Tool Support - Part 2
* Enhanced support for functions as tools via FunctionToolCallback (deprecating the existing FunctionInvokingFunctionCallback). * Aligned JSON Schema generation and parsing logic between function-based and method-based tools. * Deprecated previous client-side function calling APIs. * Included AOT configuration for Tool-annotated methods in Spring beans. Relates to gh-2049
1 parent b77e084 commit 30165fe

32 files changed

+1121
-51
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2023-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ai.aot;
18+
19+
import org.springframework.ai.tool.annotation.Tool;
20+
import org.springframework.aot.generate.GenerationContext;
21+
import org.springframework.aot.hint.MemberCategory;
22+
import org.springframework.aot.hint.ReflectionHints;
23+
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
24+
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
25+
import org.springframework.beans.factory.aot.BeanRegistrationCode;
26+
import org.springframework.beans.factory.support.RegisteredBean;
27+
import org.springframework.core.annotation.MergedAnnotations;
28+
import org.springframework.lang.Nullable;
29+
import org.springframework.util.ReflectionUtils;
30+
31+
import java.util.stream.Stream;
32+
33+
import static org.springframework.core.annotation.MergedAnnotations.SearchStrategy.TYPE_HIERARCHY;
34+
35+
/**
36+
* AOT {@code BeanRegistrationAotProcessor} that detects the presence of the {@link Tool}
37+
* annotation on methods and creates the required reflection hints.
38+
*
39+
* @author Thomas Vitale
40+
* @since 1.0.0
41+
*/
42+
class ToolBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {
43+
44+
@Override
45+
@Nullable
46+
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
47+
Class<?> beanClass = registeredBean.getBeanClass();
48+
MergedAnnotations.Search search = MergedAnnotations.search(TYPE_HIERARCHY);
49+
50+
boolean hasAnyToolAnnotatedMethods = Stream.of(ReflectionUtils.getDeclaredMethods(beanClass))
51+
.anyMatch(method -> search.from(method).isPresent(Tool.class));
52+
53+
if (hasAnyToolAnnotatedMethods) {
54+
return new AotContribution(beanClass);
55+
}
56+
57+
return null;
58+
}
59+
60+
private static class AotContribution implements BeanRegistrationAotContribution {
61+
62+
private final MemberCategory[] memberCategories = new MemberCategory[] { MemberCategory.INVOKE_DECLARED_METHODS,
63+
MemberCategory.INVOKE_PUBLIC_METHODS };
64+
65+
private final Class<?> toolClass;
66+
67+
public AotContribution(Class<?> toolClass) {
68+
this.toolClass = toolClass;
69+
}
70+
71+
@Override
72+
public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) {
73+
ReflectionHints reflectionHints = generationContext.getRuntimeHints().reflection();
74+
reflectionHints.registerType(toolClass, memberCategories);
75+
}
76+
77+
}
78+
79+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2023-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
@NonNullApi
18+
@NonNullFields
19+
package org.springframework.ai.aot;
20+
21+
import org.springframework.lang.NonNullApi;
22+
import org.springframework.lang.NonNullFields;

spring-ai-core/src/main/java/org/springframework/ai/model/function/AbstractFunctionCallback.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 the original author or authors.
2+
* Copyright 2023-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
2525
import com.fasterxml.jackson.databind.ObjectMapper;
2626

2727
import org.springframework.ai.chat.model.ToolContext;
28+
import org.springframework.ai.tool.function.FunctionToolCallback;
2829
import org.springframework.util.Assert;
2930

3031
/**
@@ -41,7 +42,9 @@
4142
* @param <I> the 3rd party service input type.
4243
* @param <O> the 3rd party service output type.
4344
* @author Christian Tzolov
45+
* @deprecated in favor of {@link FunctionToolCallback}.
4446
*/
47+
@Deprecated
4548
abstract class AbstractFunctionCallback<I, O> implements BiFunction<I, ToolContext, O>, FunctionCallback {
4649

4750
private final String name;

spring-ai-core/src/main/java/org/springframework/ai/model/function/DefaultCommonCallbackInvokingSpec.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2024-2024 the original author or authors.
2+
* Copyright 2024-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,9 +26,16 @@
2626

2727
import org.springframework.ai.model.function.FunctionCallback.CommonCallbackInvokingSpec;
2828
import org.springframework.ai.model.function.FunctionCallback.SchemaType;
29+
import org.springframework.ai.tool.function.FunctionToolCallback;
30+
import org.springframework.ai.tool.method.MethodToolCallback;
2931
import org.springframework.ai.util.JacksonUtils;
3032
import org.springframework.util.Assert;
3133

34+
/**
35+
* @deprecated Use specific builder for the type of tool you need, e.g.
36+
* {@link FunctionToolCallback.Builder} and {@link MethodToolCallback.Builder}.
37+
*/
38+
@Deprecated
3239
public class DefaultCommonCallbackInvokingSpec<B extends CommonCallbackInvokingSpec<B>>
3340
implements CommonCallbackInvokingSpec<B> {
3441

spring-ai-core/src/main/java/org/springframework/ai/model/function/DefaultFunctionCallbackBuilder.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 the original author or authors.
2+
* Copyright 2023-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -31,6 +31,8 @@
3131
import org.springframework.ai.model.function.FunctionCallback.FunctionInvokingSpec;
3232
import org.springframework.ai.model.function.FunctionCallback.MethodInvokingSpec;
3333
import org.springframework.ai.model.function.FunctionCallback.SchemaType;
34+
import org.springframework.ai.tool.function.FunctionToolCallback;
35+
import org.springframework.ai.tool.method.MethodToolCallback;
3436
import org.springframework.ai.util.ParsingUtils;
3537
import org.springframework.core.ParameterizedTypeReference;
3638
import org.springframework.util.Assert;
@@ -42,7 +44,10 @@
4244
*
4345
* @author Christian Tzolov
4446
* @since 1.0.0
47+
* @deprecated Use specific builder for the type of tool you need, e.g.
48+
* {@link FunctionToolCallback.Builder} and {@link MethodToolCallback.Builder}.
4549
*/
50+
@Deprecated
4651
public class DefaultFunctionCallbackBuilder implements FunctionCallback.Builder {
4752

4853
private static final Logger logger = LoggerFactory.getLogger(DefaultFunctionCallbackBuilder.class);

spring-ai-core/src/main/java/org/springframework/ai/model/function/DefaultFunctionCallingOptions.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2024-2024 the original author or authors.
2+
* Copyright 2024-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
2525
import java.util.Set;
2626

2727
import org.springframework.ai.chat.prompt.ChatOptions;
28+
import org.springframework.ai.model.tool.DefaultToolCallingChatOptions;
2829
import org.springframework.util.Assert;
2930
import org.springframework.util.CollectionUtils;
3031
import org.springframework.util.StringUtils;
@@ -35,7 +36,9 @@
3536
* @author Christian Tzolov
3637
* @author Thomas Vitale
3738
* @author Ilayaperumal Gopinathan
39+
* @deprecated in favor of {@link DefaultToolCallingChatOptions}.
3840
*/
41+
@Deprecated
3942
public class DefaultFunctionCallingOptions implements FunctionCallingOptions {
4043

4144
private List<FunctionCallback> functionCallbacks = new ArrayList<>();

spring-ai-core/src/main/java/org/springframework/ai/model/function/DefaultFunctionCallingOptionsBuilder.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2024-2024 the original author or authors.
2+
* Copyright 2024-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
2222
import java.util.Map;
2323
import java.util.Set;
2424

25+
import org.springframework.ai.model.tool.DefaultToolCallingChatOptions;
2526
import org.springframework.util.Assert;
2627

2728
/**
@@ -30,7 +31,9 @@
3031
* @author Christian Tzolov
3132
* @author Thomas Vitale
3233
* @author Ilayaperumal Gopinathan
34+
* @deprecated in favor of {@link DefaultToolCallingChatOptions.Builder}.
3335
*/
36+
@Deprecated
3437
public class DefaultFunctionCallingOptionsBuilder implements FunctionCallingOptions.Builder {
3538

3639
private final DefaultFunctionCallingOptions options;

spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallback.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 the original author or authors.
2+
* Copyright 2023-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,14 +24,19 @@
2424
import com.fasterxml.jackson.databind.ObjectMapper;
2525

2626
import org.springframework.ai.chat.model.ToolContext;
27+
import org.springframework.ai.tool.ToolCallback;
28+
import org.springframework.ai.tool.function.FunctionToolCallback;
29+
import org.springframework.ai.tool.method.MethodToolCallback;
2730
import org.springframework.core.ParameterizedTypeReference;
2831

2932
/**
3033
* Represents a model function call handler. Implementations are registered with the
3134
* Models and called on prompts that trigger the function call.
3235
*
3336
* @author Christian Tzolov
37+
* @deprecated in favor of {@link ToolCallback}.
3438
*/
39+
@Deprecated
3540
public interface FunctionCallback {
3641

3742
/**
@@ -115,7 +120,11 @@ enum SchemaType {
115120
* <li>{@link FunctionInvokingSpec} - The function invoking builder interface.
116121
* <li>{@link MethodInvokingSpec} - The method invoking builder interface.
117122
* </ul>
123+
*
124+
* @deprecated Use specific builder for the type of tool you need, e.g.
125+
* {@link FunctionToolCallback.Builder} and {@link MethodToolCallback.Builder}.
118126
*/
127+
@Deprecated
119128
interface Builder {
120129

121130
/**

spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionCallingOptions.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 the original author or authors.
2+
* Copyright 2023-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,14 +21,17 @@
2121
import java.util.Set;
2222

2323
import org.springframework.ai.chat.prompt.ChatOptions;
24+
import org.springframework.ai.model.tool.ToolCallingChatOptions;
2425

2526
/**
2627
* FunctionCallingOptions is a set of options that can be used to configure the function
2728
* calling behavior of the ChatModel.
2829
*
2930
* @author Christian Tzolov
3031
* @author Ilayaperumal Gopinathan
32+
* @deprecated in favor of {@link ToolCallingChatOptions}.
3133
*/
34+
@Deprecated
3235
public interface FunctionCallingOptions extends ChatOptions {
3336

3437
/**

spring-ai-core/src/main/java/org/springframework/ai/model/function/FunctionInvokingFunctionCallback.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 the original author or authors.
2+
* Copyright 2023-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
2323
import com.fasterxml.jackson.databind.ObjectMapper;
2424

2525
import org.springframework.ai.chat.model.ToolContext;
26+
import org.springframework.ai.tool.function.FunctionToolCallback;
2627
import org.springframework.util.Assert;
2728

2829
/**
@@ -34,7 +35,9 @@
3435
* @param <I> the input type
3536
* @param <O> the output type
3637
* @author Christian Tzolov
38+
* @deprecated in favor of {@link FunctionToolCallback}.
3739
*/
40+
@Deprecated
3841
public final class FunctionInvokingFunctionCallback<I, O> extends AbstractFunctionCallback<I, O> {
3942

4043
private final BiFunction<I, ToolContext, O> biFunction;

0 commit comments

Comments
 (0)