You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Nothing exposes "every configured provider, and the models each one offers" to a consuming plugin.
AiGatewayAPI.activeModel() answers only for the active provider, and only its one selected model.
LlmProvider.configuredProviders() returns LlmConfig per provider — which carries a live API key. A caller that only wants to build a model picker has to be handed every provider's credential to read a model id off the side.
The live per-provider model catalog exists, but only inside secret-manager, with no way out.
Proposed shape
Additive, all default-bodied, so an older implementor degrades rather than throwing:
LlmProvider.availableModels(): List<AiProviderModels> — the source of truth, implemented by whichever plugin owns provider configuration.
AiGatewayAPI.availableModels() — the relay. The gateway owns no catalog of its own (it's the transport and the wire formats, not the registry), so it forwards rather than tracking a second copy of the same state.
New credential-free types: AiProviderModels(providerId, providerName, models) and AiAvailableModel(id, displayName, contextLength).
Status — implemented, unpushed, blocked on a release
Working end-to-end locally across four repos. Every branch below is local only at time of filing:
repo
branch
commit
boss-plugin-api
feat/ai-provider-models-api
2330f5f
boss-plugin-secret-manager
feat/available-models-api
ae4f6cb
boss-plugin-ai-gateway
feat/available-models-relay
1344267
boss-plugin-fluck-agent
feat/available-models-picker
6427448
State of each:
boss-plugin-api — types + both interface methods. apiCheck reports it as cleanly additive; apiDump regenerated; 2 default-behaviour tests added (13 total, green). version = deliberately untouched, per the release workflow's bump-on-merge convention.
secret-manager — implements it from the same live catalog the settings picker already reads. A manual-entry provider (CUSTOM) has no catalog to ask, so its one model comes from whatever the user typed. Lands in LlmProviderSettingsApiImpl, already the file carved out to hold new-api symbols inside the existing LinkageError guard, so no new guard was needed.
ai-gateway — relays it, wrapped in runCatching for the same reason every other providers() read there is: a provider plugin built against an older api throws NoSuchMethodError at that call site. 3 tests, one simulating exactly that failure (18 total, green).
fluck-agent — model picker gains a grouped-by-provider section, refreshed as the menu opens rather than only at startup. Entries are intentionally not selectable: a turn there runs through a local CLI engine or a custom endpoint, so a provider key from Settings isn't somewhere that panel can route to yet, and making them pickable would promise a switch that does nothing. 3 tests, full suite green.
To pick this up
This repo has to release first. All three consumers currently compile against a locally built sibling jar. Nothing runs until the new surface is in a released api version.
Then bump each consumer's pin — fluck-agent's .boss-plugin-api-version (moved 1.0.78 → 1.0.87 locally, needs the real released number), and secret-manager/ai-gateway resolve newest-jar-by-mtime locally but pull the pinned release in CI.
fluck-agent had no precedent for calling a versioned api method. The containment added there follows secret-manager's: every reference to the new types lives in GatewayModelBridge, constructed inside a LinkageError guard, and the ViewModel sees only plugin-local mirror types — so on a host with an older api jar the section is absent rather than the panel being dead. Its minApiVersion was deliberately not raised; that would stop the plugin loading there entirely, for a picker section.
The gap
Nothing exposes "every configured provider, and the models each one offers" to a consuming plugin.
AiGatewayAPI.activeModel()answers only for the active provider, and only its one selected model.LlmProvider.configuredProviders()returnsLlmConfigper provider — which carries a live API key. A caller that only wants to build a model picker has to be handed every provider's credential to read a model id off the side.The live per-provider model catalog exists, but only inside secret-manager, with no way out.
Proposed shape
Additive, all default-bodied, so an older implementor degrades rather than throwing:
LlmProvider.availableModels(): List<AiProviderModels>— the source of truth, implemented by whichever plugin owns provider configuration.AiGatewayAPI.availableModels()— the relay. The gateway owns no catalog of its own (it's the transport and the wire formats, not the registry), so it forwards rather than tracking a second copy of the same state.AiProviderModels(providerId, providerName, models)andAiAvailableModel(id, displayName, contextLength).Status — implemented, unpushed, blocked on a release
Working end-to-end locally across four repos. Every branch below is local only at time of filing:
feat/ai-provider-models-api2330f5ffeat/available-models-apiae4f6cbfeat/available-models-relay1344267feat/available-models-picker6427448State of each:
apiCheckreports it as cleanly additive;apiDumpregenerated; 2 default-behaviour tests added (13 total, green).version =deliberately untouched, per the release workflow's bump-on-merge convention.LlmProviderSettingsApiImpl, already the file carved out to hold new-api symbols inside the existingLinkageErrorguard, so no new guard was needed.runCatchingfor the same reason every otherproviders()read there is: a provider plugin built against an older api throwsNoSuchMethodErrorat that call site. 3 tests, one simulating exactly that failure (18 total, green).To pick this up
.boss-plugin-api-version(moved1.0.78→1.0.87locally, needs the real released number), and secret-manager/ai-gateway resolve newest-jar-by-mtime locally but pull the pinned release in CI.Note for whoever takes it
fluck-agent had no precedent for calling a versioned api method. The containment added there follows secret-manager's: every reference to the new types lives in
GatewayModelBridge, constructed inside aLinkageErrorguard, and the ViewModel sees only plugin-local mirror types — so on a host with an older api jar the section is absent rather than the panel being dead. ItsminApiVersionwas deliberately not raised; that would stop the plugin loading there entirely, for a picker section.