Make LLM providers pluggable via auto-configuration - #69
Conversation
Register each provider's AgentOnboardingProvider through a Spring Boot @autoConfiguration class listed in the module's AutoConfiguration.imports, mirroring the plugin modules. Providers now self-register from the classpath independently of the app's component scan, instead of relying on @component being reachable under the shared ai.javaclaw package. - anthropic: AnthropticClaudeCodeConfiguration @configuration -> @autoConfiguration; onboarding provider moved to a @bean in AnthropicAgentAutoConfiguration - openai/ollama/google: drop @component, add per-module @autoConfiguration + imports - Remove dead AgentProvider (unused; isConfigured stub returned false and getDefaultChatModel would throw). Model selection is handled centrally by spring.ai.model.chat. - Add per-provider tests asserting the bean registers and the imports file names the auto-config (the only guard for provider discovery, since OnboardingControllerTest mocks AgentOnboardingProviders) - Update AGENTS.md wording
|
Great work. I checked out the branch and verified: full build + all tests green, removing a provider from One change requested before merge (auto-config ordering, see inline), the rest are minor. Follow-up idea: switch the provider deps in |
- Make Anthropic's ChatModel auto-config ordering explicit against AnthropicChatAutoConfiguration instead of relying on alphabetical package sort. - Add @ConditionalOnMissingBean, typed to the concrete provider class, to each provider's onboarding auto-config so user overrides win. - Fix the imports-file test helper to read each module's own .imports resource instead of scanning the whole classpath, so it can't pass on another module's entry.
|
Really nice work! Sorry for the delay, I was OOO. One last change and goot to merge! Thanks for your contribution! |
Each provider test class duplicated the same block for reading its module's AutoConfiguration.imports file. Extract it into a shared AutoConfigurationImportsTestSupport test fixture in base (using Files.readAllLines instead of manual stream reading) and have all four provider tests use it.
|
@arefbehboudi @rdehuyss All requested changes are addressed and pushed (commit a281139):
All review threads are resolved and |
arefbehboudi
left a comment
There was a problem hiding this comment.
Thank you @MarcosLM11!
Closes #17
What
Make the
providers/*modules self-register from the classpath the same waythe
plugins/*modules do, instead of depending on the app's component scan.Each provider now contributes its
AgentOnboardingProviderthrough a SpringBoot
@AutoConfigurationclass listed in the module'sMETA-INF/spring/…AutoConfiguration.imports. TheChatModelside was alreadyauto-configured by the Spring AI starters, so no change was needed there.
Changes
AnthropticClaudeCodeConfiguration@Configuration→@AutoConfiguration; onboarding provider moved to a@Beanin a newAnthropicAgentAutoConfiguration(keeps the Claude Code token condition).@Component, add a small per-module@AutoConfiguration+.imports.AgentProvider: it was never injected or called; itsisConfiguredstub returnedfalseandgetDefaultChatModel()would havethrown on an empty list. Active-model selection is handled centrally by
spring.ai.model.chat.auto-config and that the
.importsfile names it — currently the only guardfor provider discovery, since
OnboardingControllerTestmocksAgentOnboardingProviders.AGENTS.mdwording.Notes
auto-configuration.
spring.ai.model.chatstill selects the active model.ChatModelonly loadswhen
spring.ai.model.chat=ollama.are intentionally left out.
Testing
./gradlew compileJava test— all modules green.