1- import type { EmbeddedRunAttemptParams } from "openclaw/plugin-sdk/agent-harness-runtime" ;
2- import { resolveRuntimeExecDefaults } from "openclaw/plugin-sdk/agent-runtime" ;
31import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts" ;
42import { resolveSandboxRuntimeStatus } from "openclaw/plugin-sdk/sandbox" ;
3+ import { getSessionEntry , type SessionEntry } from "openclaw/plugin-sdk/session-store-runtime" ;
54
65type ExecHost = "sandbox" | "gateway" | "node" ;
76type ExecTarget = "auto" | ExecHost ;
8- type ExecHostOverride = Pick <
9- NonNullable < EmbeddedRunAttemptParams [ "execOverrides" ] > ,
10- "host" | "node"
11- > ;
7+
8+ type ExecHostOverride = {
9+ host ?: string ;
10+ node ?: string ;
11+ } ;
12+
13+ type AgentEntry = NonNullable < NonNullable < OpenClawConfig [ "agents" ] > [ "list" ] > [ number ] ;
14+
15+ const DEFAULT_AGENT_ID = "main" ;
16+ const VALID_AGENT_ID_PATTERN = / ^ [ a - z 0 - 9 ] [ a - z 0 - 9 _ - ] { 0 , 63 } $ / i;
17+ const INVALID_AGENT_ID_CHARS_PATTERN = / [ ^ a - z 0 - 9 _ - ] + / g;
18+ const LEADING_DASH_PATTERN = / ^ - + / ;
19+ const TRAILING_DASH_PATTERN = / - + $ / ;
1220
1321export type CodexNativeExecutionPolicy = {
1422 nativeToolSurfaceAllowed : boolean ;
@@ -20,34 +28,44 @@ export type CodexNativeExecutionPolicy = {
2028
2129export function resolveCodexNativeExecutionPolicy ( params : {
2230 config ?: OpenClawConfig ;
31+ sessionEntry ?: SessionEntry ;
2332 sessionKey ?: string ;
2433 sessionId ?: string ;
2534 agentId ?: string ;
2635 execOverrides ?: ExecHostOverride ;
2736 sandboxAvailable ?: boolean ;
2837 readRuntimeSessionEntry ?: boolean ;
2938} ) : CodexNativeExecutionPolicy {
30- const sessionKey = params . sessionKey ?. trim ( ) || params . sessionId ?. trim ( ) ;
31- const sandboxAvailable = resolveSandboxAvailable ( {
32- config : params . config ,
33- sessionKey,
34- sandboxAvailable : params . sandboxAvailable ,
35- } ) ;
36- const defaults = resolveRuntimeExecDefaults ( {
37- cfg : params . config ,
38- agentId : params . agentId ,
39- sessionKey,
40- sandboxAvailable,
41- readRuntimeSessionEntry : params . readRuntimeSessionEntry ,
42- } ) ;
43- const requestedExecHost = params . execOverrides ?. host ?? defaults . host ;
44- const effectiveExecHost = resolveEffectiveHost ( {
39+ const config = params . config ?? { } ;
40+ const sessionKey = params . sessionKey ?. trim ( ) || params . sessionId ?. trim ( ) || undefined ;
41+ const sessionEntry =
42+ params . sessionEntry ??
43+ ( params . readRuntimeSessionEntry && sessionKey
44+ ? readRuntimeSessionEntryBestEffort ( sessionKey )
45+ : undefined ) ;
46+ const sandboxAvailable =
47+ params . sandboxAvailable ??
48+ ( sessionKey
49+ ? resolveSandboxRuntimeStatus ( {
50+ cfg : config ,
51+ sessionKey,
52+ } ) . sandboxed
53+ : false ) ;
54+ const agentId = resolvePolicyAgentId ( { config, sessionKey, agentId : params . agentId } ) ;
55+ const agentExec = resolvePolicyAgentExec ( { config, agentId } ) ;
56+ const globalExec = config . tools ?. exec ;
57+ const requestedExecHost =
58+ normalizeExecTarget ( params . execOverrides ?. host ) ??
59+ normalizeExecTarget ( sessionEntry ?. execHost ) ??
60+ normalizeExecTarget ( agentExec ?. host ) ??
61+ normalizeExecTarget ( globalExec ?. host ) ??
62+ "auto" ;
63+ const effectiveExecHost = resolveEffectiveExecHost ( {
4564 requestedExecHost,
46- defaultExecHost : defaults . host ,
47- defaultEffectiveHost : defaults . effectiveHost ,
4865 sandboxAvailable,
4966 } ) ;
50- const node = params . execOverrides ?. node ?? defaults . node ;
67+ const node =
68+ params . execOverrides ?. node ?? sessionEntry ?. execNode ?? agentExec ?. node ?? globalExec ?. node ;
5169 if ( effectiveExecHost !== "node" ) {
5270 return {
5371 nativeToolSurfaceAllowed : true ,
@@ -78,34 +96,101 @@ export function formatCodexNativeNodeExecBlock(params: {
7896 ] . join ( " " ) ;
7997}
8098
81- function resolveEffectiveHost ( params : {
99+ function resolvePolicyAgentId ( params : {
100+ config : OpenClawConfig ;
101+ sessionKey ?: string ;
102+ agentId ?: string ;
103+ } ) : string {
104+ const explicitAgentId = normalizeAgentIdOrDefault ( params . agentId ) ;
105+ if ( explicitAgentId ) {
106+ return explicitAgentId ;
107+ }
108+ const sessionAgentId = parseAgentIdFromSessionKey ( params . sessionKey ) ;
109+ if ( sessionAgentId ) {
110+ return sessionAgentId ;
111+ }
112+ const agents = listAgentEntries ( params . config ) ;
113+ const defaultEntry = agents . find ( ( entry ) => entry ?. default ) ?? agents [ 0 ] ;
114+ return normalizeAgentId ( defaultEntry ?. id ) ;
115+ }
116+
117+ function resolvePolicyAgentExec ( params : {
118+ config : OpenClawConfig ;
119+ agentId : string ;
120+ } ) : ExecHostOverride | undefined {
121+ return listAgentEntries ( params . config ) . find (
122+ ( entry ) => normalizeAgentId ( entry ?. id ) === params . agentId ,
123+ ) ?. tools ?. exec ;
124+ }
125+
126+ function listAgentEntries ( config : OpenClawConfig ) : AgentEntry [ ] {
127+ return ( config . agents ?. list ?? [ ] ) . filter (
128+ ( entry ) : entry is AgentEntry => entry !== null && typeof entry === "object" ,
129+ ) ;
130+ }
131+
132+ function parseAgentIdFromSessionKey ( sessionKey ?: string ) : string | undefined {
133+ const raw = sessionKey ?. trim ( ) ;
134+ if ( ! raw ) {
135+ return undefined ;
136+ }
137+ const parts = raw . toLowerCase ( ) . split ( ":" ) . filter ( Boolean ) ;
138+ if ( parts . length < 3 || parts [ 0 ] !== "agent" || ! parts [ 2 ] ) {
139+ return undefined ;
140+ }
141+ return normalizeAgentIdOrDefault ( parts [ 1 ] ) ;
142+ }
143+
144+ function normalizeAgentIdOrDefault ( value ?: string | null ) : string | undefined {
145+ const normalized = normalizeAgentId ( value ) ;
146+ return normalized === DEFAULT_AGENT_ID && ! ( value ?? "" ) . trim ( ) ? undefined : normalized ;
147+ }
148+
149+ function normalizeAgentId ( value ?: string | null ) : string {
150+ const trimmed = ( value ?? "" ) . trim ( ) ;
151+ if ( ! trimmed ) {
152+ return DEFAULT_AGENT_ID ;
153+ }
154+ const normalized = trimmed . toLowerCase ( ) ;
155+ if ( VALID_AGENT_ID_PATTERN . test ( trimmed ) ) {
156+ return normalized ;
157+ }
158+ return (
159+ normalized
160+ . replace ( INVALID_AGENT_ID_CHARS_PATTERN , "-" )
161+ . replace ( LEADING_DASH_PATTERN , "" )
162+ . replace ( TRAILING_DASH_PATTERN , "" )
163+ . slice ( 0 , 64 ) || DEFAULT_AGENT_ID
164+ ) ;
165+ }
166+
167+ function normalizeExecTarget ( value ?: string | null ) : ExecTarget | undefined {
168+ const normalized = value ?. trim ( ) . toLowerCase ( ) ;
169+ if (
170+ normalized === "auto" ||
171+ normalized === "sandbox" ||
172+ normalized === "gateway" ||
173+ normalized === "node"
174+ ) {
175+ return normalized ;
176+ }
177+ return undefined ;
178+ }
179+
180+ function resolveEffectiveExecHost ( params : {
82181 requestedExecHost : ExecTarget ;
83- defaultExecHost : ExecTarget ;
84- defaultEffectiveHost : ExecHost ;
85182 sandboxAvailable : boolean ;
86183} ) : ExecHost {
87- if ( params . requestedExecHost !== "auto" ) {
88- return params . requestedExecHost ;
89- }
90- if ( params . defaultExecHost === "auto" ) {
91- return params . defaultEffectiveHost ;
184+ if ( params . requestedExecHost === "auto" ) {
185+ return params . sandboxAvailable ? "sandbox" : "gateway" ;
92186 }
93- return params . sandboxAvailable ? "sandbox" : "gateway" ;
187+ return params . requestedExecHost ;
94188}
95189
96- function resolveSandboxAvailable ( params : {
97- config ?: OpenClawConfig ;
98- sessionKey ?: string ;
99- sandboxAvailable ?: boolean ;
100- } ) : boolean {
101- if ( params . sandboxAvailable !== undefined ) {
102- return params . sandboxAvailable ;
103- }
104- if ( ! params . sessionKey ) {
105- return false ;
190+ function readRuntimeSessionEntryBestEffort ( sessionKey : string ) : SessionEntry | undefined {
191+ try {
192+ return getSessionEntry ( { sessionKey } ) ;
193+ } catch {
194+ return undefined ;
106195 }
107- return resolveSandboxRuntimeStatus ( {
108- cfg : params . config ,
109- sessionKey : params . sessionKey ,
110- } ) . sandboxed ;
111196}
0 commit comments