22import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id" ;
33import { asDateTimestampMs } from "@openclaw/normalization-core/number-coercion" ;
44import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce" ;
5+ import type { OpenClawConfig } from "../config/types.openclaw.js" ;
56import { coerceSecretRef } from "../config/types.secrets.js" ;
6- import type { AuthProfileCredential , AuthProfileStore } from "./auth-profiles.js" ;
7+ import { resolveAuthProfileOrder } from "./auth-profiles/order.js" ;
8+ import type { AuthProfileCredential , AuthProfileStore } from "./auth-profiles/types.js" ;
79
810// Converts auth-profile credentials into the compact credential map consumed by
911// agent runtimes. Secret refs can be represented by markers without reading
@@ -22,6 +24,7 @@ export type AgentCredentialMap = Record<string, AgentCredential>;
2224
2325type ResolveAgentCredentialMapOptions = {
2426 includeSecretRefPlaceholders ?: boolean ;
27+ config ?: OpenClawConfig ;
2528} ;
2629
2730const AGENT_SECRET_REF_CONFIGURED_MARKER = "openclaw-secret-ref-configured" ;
@@ -85,20 +88,38 @@ function convertAuthProfileCredentialToAgent(
8588 return null ;
8689}
8790
88- /** Build one credential per normalized provider from an auth profile store . */
91+ /** Build one canonically selected credential per normalized provider. */
8992export function resolveAgentCredentialMapFromStore (
9093 store : AuthProfileStore ,
9194 options ?: ResolveAgentCredentialMapOptions ,
9295) : AgentCredentialMap {
9396 const credentials : AgentCredentialMap = { } ;
9497 for ( const credential of Object . values ( store . profiles ) ) {
9598 const provider = normalizeProviderId ( credential . provider ?? "" ) ;
96- if ( ! provider || credentials [ provider ] ) {
99+ if ( ! provider ) {
97100 continue ;
98101 }
99- const converted = convertAuthProfileCredentialToAgent ( credential , options ) ;
100- if ( converted ) {
101- credentials [ provider ] = converted ;
102+ if ( credentials [ provider ] ) {
103+ continue ;
104+ }
105+ // Discovery must not grow a second auth policy: explicit order, provider
106+ // aliases, eligibility, and automatic preference all belong to this resolver.
107+ const profileIds = resolveAuthProfileOrder ( {
108+ cfg : options ?. config ,
109+ store,
110+ provider,
111+ ...( options ?. includeSecretRefPlaceholders === true ? { readinessMode : "read-only" } : { } ) ,
112+ } ) ;
113+ for ( const profileId of profileIds ) {
114+ const profile = store . profiles [ profileId ] ;
115+ if ( ! profile ) {
116+ continue ;
117+ }
118+ const converted = convertAuthProfileCredentialToAgent ( profile , options ) ;
119+ if ( converted ) {
120+ credentials [ provider ] = converted ;
121+ break ;
122+ }
102123 }
103124 }
104125 return credentials ;
0 commit comments