@@ -11,6 +11,14 @@ type modelCountProvider interface {
1111 ModelCount () int
1212}
1313
14+ type providerModelRefresher interface {
15+ RefreshProviderModels (ctx context.Context , providerSelector string ) (int , error )
16+ }
17+
18+ type modelRefreshTargetResolver interface {
19+ ResolveRefreshTarget (requested core.RequestedModelSelector ) (core.ModelSelector , bool , error )
20+ }
21+
1422// ResolvedProviderName returns the configured provider instance name for a selector.
1523func ResolvedProviderName (provider core.RoutableProvider , selector core.ModelSelector , fallback string ) string {
1624 fallback = strings .TrimSpace (fallback )
@@ -64,8 +72,20 @@ func ResolveRequestModelWithAuthorizer(
6472 requested = core .NewRequestedModelSelector (requested .Model , requested .ProviderHint )
6573
6674 resolvedSelector , aliasApplied , err := ResolveExecutionSelector (provider , resolver , requested )
75+ refreshed := false
6776 if err != nil {
68- return nil , core .NewInvalidRequestError (err .Error (), err )
77+ var refreshErr error
78+ refreshed , refreshErr = refreshProviderModelsForResolution (ctx , provider , resolver , requested , resolvedSelector )
79+ if refreshErr != nil {
80+ return nil , refreshErr
81+ }
82+ if ! refreshed {
83+ return nil , core .NewInvalidRequestError (err .Error (), err )
84+ }
85+ resolvedSelector , aliasApplied , err = ResolveExecutionSelector (provider , resolver , requested )
86+ if err != nil {
87+ return nil , core .NewInvalidRequestError (err .Error (), err )
88+ }
6989 }
7090 if resolvedSelector == (core.ModelSelector {}) {
7191 resolvedSelector , err = requested .Normalize ()
@@ -75,9 +95,41 @@ func ResolveRequestModelWithAuthorizer(
7595 }
7696
7797 resolvedModel := resolvedSelector .QualifiedModel ()
98+ if counted , ok := provider .(modelCountProvider ); ok && counted .ModelCount () == 0 {
99+ if ! refreshed {
100+ var refreshErr error
101+ refreshed , refreshErr = refreshProviderModelsForResolution (ctx , provider , resolver , requested , resolvedSelector )
102+ if refreshErr != nil {
103+ return nil , refreshErr
104+ }
105+ if refreshed {
106+ resolvedSelector , aliasApplied , err = ResolveExecutionSelector (provider , resolver , requested )
107+ if err != nil {
108+ return nil , core .NewInvalidRequestError (err .Error (), err )
109+ }
110+ resolvedModel = resolvedSelector .QualifiedModel ()
111+ }
112+ }
113+ }
78114 if counted , ok := provider .(modelCountProvider ); ok && counted .ModelCount () == 0 {
79115 return nil , core .NewProviderError ("" , 0 , "model registry not initialized" , nil )
80116 }
117+ if ! provider .Supports (resolvedModel ) {
118+ if ! refreshed {
119+ var refreshErr error
120+ refreshed , refreshErr = refreshProviderModelsForResolution (ctx , provider , resolver , requested , resolvedSelector )
121+ if refreshErr != nil {
122+ return nil , refreshErr
123+ }
124+ if refreshed {
125+ resolvedSelector , aliasApplied , err = ResolveExecutionSelector (provider , resolver , requested )
126+ if err != nil {
127+ return nil , core .NewInvalidRequestError (err .Error (), err )
128+ }
129+ resolvedModel = resolvedSelector .QualifiedModel ()
130+ }
131+ }
132+ }
81133 if ! provider .Supports (resolvedModel ) {
82134 return nil , core .NewInvalidRequestError ("unsupported model: " + resolvedModel , nil )
83135 }
@@ -96,6 +148,45 @@ func ResolveRequestModelWithAuthorizer(
96148 }, nil
97149}
98150
151+ func refreshProviderModelsForResolution (
152+ ctx context.Context ,
153+ provider core.RoutableProvider ,
154+ resolver ModelResolver ,
155+ requested core.RequestedModelSelector ,
156+ resolvedSelector core.ModelSelector ,
157+ ) (bool , error ) {
158+ refresher , ok := provider .(providerModelRefresher )
159+ if ! ok {
160+ return false , nil
161+ }
162+
163+ providerSelector := strings .TrimSpace (resolvedSelector .Provider )
164+ if providerSelector == "" {
165+ if targetResolver , ok := resolver .(modelRefreshTargetResolver ); ok {
166+ selector , ok , err := targetResolver .ResolveRefreshTarget (requested )
167+ if err != nil {
168+ return false , err
169+ }
170+ if ok {
171+ providerSelector = strings .TrimSpace (selector .Provider )
172+ }
173+ }
174+ }
175+ if providerSelector == "" {
176+ selector , err := requested .Normalize ()
177+ if err != nil {
178+ return false , nil
179+ }
180+ providerSelector = strings .TrimSpace (selector .Provider )
181+ }
182+ if providerSelector == "" {
183+ return false , nil
184+ }
185+
186+ _ , err := refresher .RefreshProviderModels (ctx , providerSelector )
187+ return true , err
188+ }
189+
99190// ResolveExecutionSelector applies explicit and provider-owned selector resolution.
100191func ResolveExecutionSelector (
101192 provider core.RoutableProvider ,
@@ -119,12 +210,15 @@ func ResolveExecutionSelector(
119210 }
120211
121212 if providerResolver , ok := provider .(ModelResolver ); ok {
122- var providerChanged bool
123- resolvedSelector , providerChanged , err = providerResolver .ResolveModel (requested )
213+ providerSelector , providerChanged , err := providerResolver .ResolveModel (requested )
124214 if err != nil {
215+ if resolvedSelector != (core.ModelSelector {}) {
216+ // Preserve alias targets so callers can refresh the concrete provider before retrying.
217+ return resolvedSelector , aliasApplied , err
218+ }
125219 return core.ModelSelector {}, false , err
126220 }
127- return resolvedSelector , aliasApplied || providerChanged , nil
221+ return providerSelector , aliasApplied || providerChanged , nil
128222 }
129223
130224 if resolvedSelector != (core.ModelSelector {}) {
0 commit comments