@@ -5,13 +5,15 @@ import {
55} from "../../config/model-input.js" ;
66import type { AgentToolModelConfig } from "../../config/types.agents-shared.js" ;
77import type { OpenClawConfig } from "../../config/types.openclaw.js" ;
8+ import { coerceSecretRef } from "../../config/types.secrets.js" ;
9+ import { normalizeOptionalSecretInput } from "../../utils/normalize-secret-input.js" ;
810import {
911 externalCliDiscoveryForProviderAuth ,
1012 ensureAuthProfileStore ,
1113 hasAnyAuthProfileStoreSource ,
1214 listProfilesForProvider ,
1315} from "../auth-profiles.js" ;
14- import type { AuthProfileStore } from "../auth-profiles/types.js" ;
16+ import type { AuthProfileCredential , AuthProfileStore } from "../auth-profiles/types.js" ;
1517import { DEFAULT_MODEL , DEFAULT_PROVIDER } from "../defaults.js" ;
1618import {
1719 hasRuntimeAvailableProviderAuth ,
@@ -43,14 +45,19 @@ export function resolveDefaultModelRef(cfg?: OpenClawConfig): { provider: string
4345
4446export function hasAuthForProvider ( params : {
4547 provider : string ;
48+ cfg ?: OpenClawConfig ;
4649 agentDir ?: string ;
4750 authStore ?: AuthProfileStore ;
4851} ) : boolean {
4952 if ( resolveEnvApiKey ( params . provider ) ?. apiKey ) {
5053 return true ;
5154 }
5255 if ( params . authStore ) {
53- return listProfilesForProvider ( params . authStore , params . provider ) . length > 0 ;
56+ return hasUsableProfileForProvider ( {
57+ store : params . authStore ,
58+ provider : params . provider ,
59+ cfg : params . cfg ,
60+ } ) ;
5461 }
5562 const agentDir = params . agentDir ?. trim ( ) ;
5663 if ( ! agentDir ) {
@@ -62,7 +69,71 @@ export function hasAuthForProvider(params: {
6269 const store = ensureAuthProfileStore ( agentDir , {
6370 externalCli : externalCliDiscoveryForProviderAuth ( { provider : params . provider } ) ,
6471 } ) ;
65- return listProfilesForProvider ( store , params . provider ) . length > 0 ;
72+ return hasUsableProfileForProvider ( {
73+ store,
74+ provider : params . provider ,
75+ cfg : params . cfg ,
76+ } ) ;
77+ }
78+
79+ function hasUsableProfileForProvider ( params : {
80+ store : AuthProfileStore ;
81+ provider : string ;
82+ cfg ?: OpenClawConfig ;
83+ } ) : boolean {
84+ return listProfilesForProvider ( params . store , params . provider ) . some ( ( profileId ) => {
85+ const credential = params . store . profiles [ profileId ] ;
86+ return Boolean ( credential && hasUsableProfileCredential ( { credential, cfg : params . cfg } ) ) ;
87+ } ) ;
88+ }
89+
90+ function hasUsableProfileCredential ( params : {
91+ credential : AuthProfileCredential ;
92+ cfg ?: OpenClawConfig ;
93+ } ) : boolean {
94+ if ( params . credential . type === "api_key" ) {
95+ return (
96+ hasAvailableProfileSecretInput ( {
97+ value : params . credential . key ,
98+ cfg : params . cfg ,
99+ } ) ||
100+ hasAvailableProfileSecretInput ( {
101+ value : params . credential . keyRef ,
102+ cfg : params . cfg ,
103+ } )
104+ ) ;
105+ }
106+ if ( params . credential . type === "token" ) {
107+ if ( typeof params . credential . expires === "number" && params . credential . expires <= Date . now ( ) ) {
108+ return false ;
109+ }
110+ return (
111+ hasAvailableProfileSecretInput ( {
112+ value : params . credential . token ,
113+ cfg : params . cfg ,
114+ } ) ||
115+ hasAvailableProfileSecretInput ( {
116+ value : params . credential . tokenRef ,
117+ cfg : params . cfg ,
118+ } )
119+ ) ;
120+ }
121+ return Boolean (
122+ normalizeOptionalSecretInput ( params . credential . access ) ||
123+ normalizeOptionalSecretInput ( params . credential . refresh ) ||
124+ normalizeOptionalSecretInput ( params . credential . idToken ) ,
125+ ) ;
126+ }
127+
128+ function hasAvailableProfileSecretInput ( params : { value : unknown ; cfg ?: OpenClawConfig } ) : boolean {
129+ const ref = coerceSecretRef ( params . value , params . cfg ?. secrets ?. defaults ) ;
130+ if ( ref ) {
131+ if ( ref . source === "env" ) {
132+ return Boolean ( normalizeOptionalSecretInput ( process . env [ ref . id ] ) ) ;
133+ }
134+ return true ;
135+ }
136+ return Boolean ( normalizeOptionalSecretInput ( params . value ) ) ;
66137}
67138
68139export function hasProviderAuthForTool ( params : {
@@ -75,6 +146,7 @@ export function hasProviderAuthForTool(params: {
75146 if (
76147 hasAuthForProvider ( {
77148 provider : params . provider ,
149+ cfg : params . cfg ,
78150 agentDir : params . agentDir ,
79151 authStore : params . authStore ,
80152 } )
0 commit comments