Skip to content

Commit 320dd83

Browse files
committed
Support Spring Security oauth2 flows in tool calling
Signed-off-by: Daniel Garnier-Moiroux <[email protected]>
1 parent 35b80ed commit 320dd83

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

auto-configurations/models/tool/spring-ai-autoconfigure-model-tool/src/main/java/org/springframework/ai/model/tool/autoconfigure/ToolCallingAutoConfiguration.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616

1717
package org.springframework.ai.model.tool.autoconfigure;
1818

19+
import io.micrometer.observation.ObservationRegistry;
1920
import java.util.ArrayList;
2021
import java.util.List;
21-
22-
import io.micrometer.observation.ObservationRegistry;
2322
import org.slf4j.Logger;
2423
import org.slf4j.LoggerFactory;
2524

@@ -43,12 +42,14 @@
4342
import org.springframework.boot.context.properties.EnableConfigurationProperties;
4443
import org.springframework.context.annotation.Bean;
4544
import org.springframework.context.support.GenericApplicationContext;
45+
import org.springframework.util.ClassUtils;
4646

4747
/**
4848
* Auto-configuration for common tool calling features of {@link ChatModel}.
4949
*
5050
* @author Thomas Vitale
5151
* @author Christian Tzolov
52+
* @author Daniel Garnier-Moiroux
5253
* @since 1.0.0
5354
*/
5455
@AutoConfiguration
@@ -78,7 +79,21 @@ ToolCallbackResolver toolCallbackResolver(GenericApplicationContext applicationC
7879
@Bean
7980
@ConditionalOnMissingBean
8081
ToolExecutionExceptionProcessor toolExecutionExceptionProcessor(ToolCallingProperties properties) {
81-
return new DefaultToolExecutionExceptionProcessor(properties.isThrowExceptionOnError());
82+
ArrayList<Class<? extends RuntimeException>> rethrownExceptions = new ArrayList<>();
83+
84+
// ClientAuthorizationException is used by Spring Security in oauth2 flows,
85+
// for example with ServletOAuth2AuthorizedClientExchangeFilterFunction and
86+
// OAuth2ClientHttpRequestInterceptor.
87+
Class<? extends RuntimeException> oauth2Exception = getClassOrNull(
88+
"org.springframework.security.oauth2.client.ClientAuthorizationException");
89+
if (oauth2Exception != null) {
90+
rethrownExceptions.add(oauth2Exception);
91+
}
92+
93+
return DefaultToolExecutionExceptionProcessor.builder()
94+
.alwaysThrow(properties.isThrowExceptionOnError())
95+
.rethrowExceptions(rethrownExceptions)
96+
.build();
8297
}
8398

8499
@Bean
@@ -108,4 +123,14 @@ ToolCallingContentObservationFilter toolCallingContentObservationFilter() {
108123
return new ToolCallingContentObservationFilter();
109124
}
110125

126+
private static Class<? extends RuntimeException> getClassOrNull(String className) {
127+
try {
128+
return (Class<? extends RuntimeException>) ClassUtils.forName(className, null);
129+
}
130+
catch (ClassNotFoundException e) {
131+
logger.debug("Cannot load class", e);
132+
}
133+
return null;
134+
}
135+
111136
}

0 commit comments

Comments
 (0)