11import type { OpenClawConfig } from "../config/types.openclaw.js" ;
22import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js" ;
33import { isRecord } from "../utils.js" ;
4- import { resolveModelRuntimePolicy } from "./model-runtime-policy.js" ;
5- import { modelSelectionShouldEnsureCodexPlugin } from "./openai-codex-routing.js" ;
4+ import { resolveAgentHarnessPolicy } from "./harness/policy.js" ;
65import { normalizeEmbeddedAgentRuntime } from "./pi-embedded-runner/runtime.js" ;
76import { normalizeProviderId } from "./provider-id.js" ;
87
@@ -38,6 +37,12 @@ function listAgentModelRefs(value: unknown): string[] {
3837 return refs ;
3938}
4039
40+ function pushAgentModelRefs ( refs : string [ ] , value : unknown ) : void {
41+ for ( const ref of listAgentModelRefs ( value ) ) {
42+ refs . push ( ref ) ;
43+ }
44+ }
45+
4146function parseConfiguredModelRef (
4247 value : unknown ,
4348) : { provider : string ; modelId : string } | undefined {
@@ -55,21 +60,23 @@ function parseConfiguredModelRef(
5560 } ;
5661}
5762
58- function hasOpenAIModelRef ( config : OpenClawConfig , value : unknown , agentId ?: string ) : boolean {
59- return listAgentModelRefs ( value ) . some ( ( ref ) => {
60- if ( ! modelSelectionShouldEnsureCodexPlugin ( { model : ref , config } ) ) {
61- return false ;
62- }
63- const parsed = parseConfiguredModelRef ( ref ) ;
64- const policy = resolveModelRuntimePolicy ( {
65- config ,
66- provider : parsed ?. provider ,
67- modelId : parsed ?. modelId ,
68- agentId ,
69- } ) ;
70- const runtime = normalizeRuntimeId ( policy . policy ?. id ) ;
71- return ! runtime || runtime === "auto" || runtime === "codex" ;
63+ function resolveConfiguredModelHarnessRuntime ( params : {
64+ config : OpenClawConfig ;
65+ modelRef : string ;
66+ agentId ?: string ;
67+ } ) : string | undefined {
68+ const parsed = parseConfiguredModelRef ( params . modelRef ) ;
69+ if ( ! parsed ) {
70+ return undefined ;
71+ }
72+ const policy = resolveAgentHarnessPolicy ( {
73+ config : params . config ,
74+ provider : parsed . provider ,
75+ modelId : parsed . modelId ,
76+ agentId : params . agentId ,
7277 } ) ;
78+ const runtime = normalizeRuntimeId ( policy . runtime ) ;
79+ return runtime && runtime !== "auto" && runtime !== "pi" ? runtime : undefined ;
7380}
7481
7582function pushConfiguredModelRuntimeIds ( config : OpenClawConfig , runtimes : Set < string > ) : void {
@@ -104,7 +111,44 @@ function pushConfiguredModelRuntimeIds(config: OpenClawConfig, runtimes: Set<str
104111 pushModelMapRuntimeIds ( config . agents ?. defaults ?. models ) ;
105112 const agents = Array . isArray ( config . agents ?. list ) ? config . agents . list : [ ] ;
106113 for ( const agent of agents ) {
107- pushModelMapRuntimeIds ( agent . models ) ;
114+ pushModelMapRuntimeIds ( isRecord ( agent ) ? agent . models : undefined ) ;
115+ }
116+ }
117+
118+ function pushConfiguredAgentModelRuntimeIds ( config : OpenClawConfig , runtimes : Set < string > ) : void {
119+ const pushModelRefs = ( modelRefs : string [ ] , agentId ?: string ) => {
120+ for ( const modelRef of modelRefs ) {
121+ const runtime = resolveConfiguredModelHarnessRuntime ( { config, modelRef, agentId } ) ;
122+ if ( runtime ) {
123+ runtimes . add ( runtime ) ;
124+ }
125+ }
126+ } ;
127+ const pushModelMapRefs = ( models : unknown , agentId ?: string ) => {
128+ if ( ! isRecord ( models ) ) {
129+ return ;
130+ }
131+ pushModelRefs ( Object . keys ( models ) , agentId ) ;
132+ } ;
133+
134+ const defaultsModel = config . agents ?. defaults ?. model ;
135+ const defaultsModelRefs : string [ ] = [ ] ;
136+ pushAgentModelRefs ( defaultsModelRefs , defaultsModel ) ;
137+ pushModelRefs ( defaultsModelRefs ) ;
138+ pushModelMapRefs ( config . agents ?. defaults ?. models ) ;
139+
140+ if ( ! Array . isArray ( config . agents ?. list ) ) {
141+ return ;
142+ }
143+ for ( const agent of config . agents . list ) {
144+ if ( ! isRecord ( agent ) ) {
145+ continue ;
146+ }
147+ const agentId = typeof agent . id === "string" ? agent . id : undefined ;
148+ const selectedModelRefs : string [ ] = [ ] ;
149+ pushAgentModelRefs ( selectedModelRefs , agent . model ?? defaultsModel ) ;
150+ pushModelRefs ( selectedModelRefs , agentId ) ;
151+ pushModelMapRefs ( agent . models , agentId ) ;
108152 }
109153}
110154
@@ -136,11 +180,6 @@ export function collectConfiguredAgentHarnessRuntimes(
136180 const runtimes = new Set < string > ( ) ;
137181 const includeEnvRuntime = options . includeEnvRuntime ?? true ;
138182 const includeLegacyAgentRuntimes = options . includeLegacyAgentRuntimes ?? true ;
139- const pushCodexForOpenAIModel = ( model : unknown , agentId ?: string ) => {
140- if ( hasOpenAIModelRef ( config , model , agentId ) ) {
141- runtimes . add ( "codex" ) ;
142- }
143- } ;
144183
145184 if ( includeEnvRuntime ) {
146185 const envRuntime = normalizeRuntimeId ( env . OPENCLAW_AGENT_RUNTIME ) ;
@@ -152,19 +191,7 @@ export function collectConfiguredAgentHarnessRuntimes(
152191 if ( includeLegacyAgentRuntimes ) {
153192 pushLegacyAgentRuntimeIds ( config , runtimes ) ;
154193 }
155- const defaultsModel = config . agents ?. defaults ?. model ;
156- pushCodexForOpenAIModel ( defaultsModel ) ;
157- if ( Array . isArray ( config . agents ?. list ) ) {
158- for ( const agent of config . agents . list ) {
159- if ( ! isRecord ( agent ) ) {
160- continue ;
161- }
162- pushCodexForOpenAIModel (
163- agent . model ?? defaultsModel ,
164- typeof agent . id === "string" ? agent . id : undefined ,
165- ) ;
166- }
167- }
194+ pushConfiguredAgentModelRuntimeIds ( config , runtimes ) ;
168195
169196 return [ ...runtimes ] . toSorted ( ( left , right ) => left . localeCompare ( right ) ) ;
170197}
0 commit comments