@parall/codex-agent 1.36.0 → 1.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.js +37 -41
  2. package/package.json +4 -4
  3. package/src/index.ts +41 -44
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import * as os from 'node:os';
3
- import { ParallAgentGateway, createPlatformConfigManager, createLogger, createOtelLogger, childLogger, isPlatformManagedProfile, isPlatformModelOverride, resolveRuntimeModel, parseShutdownDeadlineMs, parseForkDeadlineMs, parseDispatchDeadlineMs, parseProviderConfig, clearAllProviderCreds, llmSource, initAgentTelemetry, } from '@parall/agent-core';
3
+ import { ParallAgentGateway, createPlatformConfigManager, createLogger, createOtelLogger, childLogger, deriveModelIsPin, resolveRuntimeModel, parseShutdownDeadlineMs, parseForkDeadlineMs, parseDispatchDeadlineMs, parseProviderConfig, clearAllProviderCreds, llmSource, initAgentTelemetry, } from '@parall/agent-core';
4
4
  import { ApiError, ParallClient, ParallWs } from '@parall/sdk';
5
5
  import { buildCodexRuntimeKey, contextFilePathForSession, resolveCodexAgentConfig, resolveWsUrl, sessionStateFilePathForRuntime, stepIdFilePathForSession, } from './config.js';
6
6
  import { CodexAppServerAdapter } from './dispatch.js';
@@ -79,25 +79,18 @@ async function main() {
79
79
  log: agentLog,
80
80
  });
81
81
  const platformDefaults = await configMgr.fetch();
82
- let platformManaged = isPlatformManagedProfile(me.agent_profile);
83
- // Model precedence: operator override (platform-managed) > env > server floor.
84
- // The server delivers a model floor for Parall-proxy routes even when
85
- // model_management=self, so the CLI never falls back to a built-in default
86
- // the catalog might reject but that floor must lose to an explicit env
87
- // override. A profile is an operator-override only when it is platform-managed
88
- // AND not explicitly self-managed: this treats legacy hosted agents
89
- // (model_management=null, resolved to platform server-side) as overrides,
90
- // while excluding local self agents whose delivered model is a floor.
91
- // reasoning_effort stays an operator override (platform).
92
- let platformModelOverride = isPlatformModelOverride(me.agent_profile);
82
+ // Model precedence: operator PIN (override) > env > server FLOOR. The server
83
+ // now says which it is via model_is_pin (deriveModelIsPin presence-gates the
84
+ // dual-read: old servers omit it fall back to model_management). A PIN beats
85
+ // an explicit env override; a FLOOR loses to env. reasoning_effort is delivered
86
+ // by the server only when pinned, so we no longer gate it on a local flag.
87
+ const platformModelOverride = deriveModelIsPin(platformDefaults, me.agent_profile);
93
88
  const resolvedModel = resolveRuntimeModel(platformModelOverride, platformDefaults.model, config.model);
94
- const resolvedEffort = platformManaged
95
- ? (platformDefaults.thinkingEffort ?? config.reasoningEffort)
96
- : config.reasoningEffort;
89
+ const resolvedEffort = platformDefaults.thinkingEffort ?? config.reasoningEffort;
97
90
  if (platformDefaults.model)
98
- agentLog.info(`platform config: model=${platformDefaults.model} → resolved=${resolvedModel ?? 'cli-default'} (${platformModelOverride ? 'platform-managed' : 'floor/self'})`);
91
+ agentLog.info(`platform config: model=${platformDefaults.model} → resolved=${resolvedModel ?? 'cli-default'} (${platformModelOverride ? 'pin/override' : 'floor'})`);
99
92
  if (platformDefaults.thinkingEffort)
100
- agentLog.info(`platform config: reasoning_effort=${platformDefaults.thinkingEffort} (${platformModelOverride ? 'applied' : 'ignored, model_management=self'})`);
93
+ agentLog.info(`platform config: reasoning_effort=${platformDefaults.thinkingEffort}`);
101
94
  const adapter = new CodexAppServerAdapter({
102
95
  codexBin: config.codexBin,
103
96
  codexHome: config.codexHome,
@@ -111,6 +104,31 @@ async function main() {
111
104
  contextFilePath: mainContextFilePath,
112
105
  useParallProvider,
113
106
  });
107
+ // Shared by onConfigUpdate + onSessionReady. /agents/me is only consumed as
108
+ // deriveModelIsPin's legacy fallback when the server omits model_is_pin
109
+ // (old server) — skip that round trip otherwise.
110
+ const refreshPlatformConfig = async () => {
111
+ const updated = await configMgr.fetch();
112
+ let refreshedProfile;
113
+ if (updated.modelIsPin === undefined) {
114
+ try {
115
+ refreshedProfile = (await getAgentMeWithLegacyFallback(client, config.orgId))
116
+ .agent_profile;
117
+ }
118
+ catch (err) {
119
+ // configMgr.fetch() degrades to cache on failure; mirror that for the
120
+ // legacy fallback so a transient /agents/me error doesn't reject this
121
+ // config-refresh callback. No profile → deriveModelIsPin treats the
122
+ // delivered model as a floor (safe default).
123
+ agentLog.warn(`platform config refresh: legacy /agents/me fallback failed: ${String(err)}`);
124
+ }
125
+ }
126
+ const isPin = deriveModelIsPin(updated, refreshedProfile);
127
+ adapter.updateConfig({
128
+ model: resolveRuntimeModel(isPin, updated.model, config.model) ?? null,
129
+ reasoningEffort: updated.thinkingEffort ?? config.reasoningEffort ?? null,
130
+ });
131
+ };
114
132
  const gateway = new ParallAgentGateway({
115
133
  accountId: agentUserId,
116
134
  client,
@@ -138,30 +156,8 @@ async function main() {
138
156
  dispatchDeadlineMs: parseDispatchDeadlineMs(process.env.PRLL_DISPATCH_DEADLINE_MS),
139
157
  contextFilePathForSession: (sessionKey) => contextFilePathForSession(config.stateDir, sessionKey),
140
158
  stepIdFilePathForSession: (sessionKey) => stepIdFilePathForSession(config.stateDir, sessionKey),
141
- onConfigUpdate: async () => {
142
- const refreshed = await getAgentMeWithLegacyFallback(client, config.orgId);
143
- platformManaged = isPlatformManagedProfile(refreshed.agent_profile);
144
- platformModelOverride = isPlatformModelOverride(refreshed.agent_profile);
145
- const updated = await configMgr.fetch();
146
- adapter.updateConfig({
147
- model: resolveRuntimeModel(platformModelOverride, updated.model, config.model) ?? null,
148
- reasoningEffort: platformManaged
149
- ? (updated.thinkingEffort ?? config.reasoningEffort)
150
- : (config.reasoningEffort ?? null),
151
- });
152
- },
153
- onSessionReady: async () => {
154
- const refreshed = await getAgentMeWithLegacyFallback(client, config.orgId);
155
- platformManaged = isPlatformManagedProfile(refreshed.agent_profile);
156
- platformModelOverride = isPlatformModelOverride(refreshed.agent_profile);
157
- const updated = await configMgr.fetch();
158
- adapter.updateConfig({
159
- model: resolveRuntimeModel(platformModelOverride, updated.model, config.model) ?? null,
160
- reasoningEffort: platformManaged
161
- ? (updated.thinkingEffort ?? config.reasoningEffort)
162
- : (config.reasoningEffort ?? null),
163
- });
164
- },
159
+ onConfigUpdate: refreshPlatformConfig,
160
+ onSessionReady: refreshPlatformConfig,
165
161
  onNewSession: () => {
166
162
  sessionManager.clearMainThread();
167
163
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parall/codex-agent",
3
- "version": "1.36.0",
3
+ "version": "1.37.0",
4
4
  "description": "Codex CLI bridge runtime for self-hosted Parall agents",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -26,9 +26,9 @@
26
26
  ],
27
27
  "dependencies": {
28
28
  "smol-toml": "^1.6.1",
29
- "@parall/agent-core": "1.36.0",
30
- "@parall/sdk": "1.36.0",
31
- "@parall/cli": "1.36.0"
29
+ "@parall/agent-core": "1.37.0",
30
+ "@parall/cli": "1.37.0",
31
+ "@parall/sdk": "1.37.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/node": "^22.0.0",
package/src/index.ts CHANGED
@@ -7,8 +7,7 @@ import {
7
7
  createLogger,
8
8
  createOtelLogger,
9
9
  childLogger,
10
- isPlatformManagedProfile,
11
- isPlatformModelOverride,
10
+ deriveModelIsPin,
12
11
  resolveRuntimeModel,
13
12
  parseShutdownDeadlineMs,
14
13
  parseForkDeadlineMs,
@@ -111,33 +110,24 @@ async function main() {
111
110
  log: agentLog,
112
111
  });
113
112
  const platformDefaults = await configMgr.fetch();
114
- let platformManaged = isPlatformManagedProfile(me.agent_profile);
115
- // Model precedence: operator override (platform-managed) > env > server floor.
116
- // The server delivers a model floor for Parall-proxy routes even when
117
- // model_management=self, so the CLI never falls back to a built-in default
118
- // the catalog might reject but that floor must lose to an explicit env
119
- // override. A profile is an operator-override only when it is platform-managed
120
- // AND not explicitly self-managed: this treats legacy hosted agents
121
- // (model_management=null, resolved to platform server-side) as overrides,
122
- // while excluding local self agents whose delivered model is a floor.
123
- // reasoning_effort stays an operator override (platform).
124
- let platformModelOverride = isPlatformModelOverride(me.agent_profile);
113
+ // Model precedence: operator PIN (override) > env > server FLOOR. The server
114
+ // now says which it is via model_is_pin (deriveModelIsPin presence-gates the
115
+ // dual-read: old servers omit it fall back to model_management). A PIN beats
116
+ // an explicit env override; a FLOOR loses to env. reasoning_effort is delivered
117
+ // by the server only when pinned, so we no longer gate it on a local flag.
118
+ const platformModelOverride = deriveModelIsPin(platformDefaults, me.agent_profile);
125
119
  const resolvedModel = resolveRuntimeModel(
126
120
  platformModelOverride,
127
121
  platformDefaults.model,
128
122
  config.model,
129
123
  );
130
- const resolvedEffort = platformManaged
131
- ? (platformDefaults.thinkingEffort ?? config.reasoningEffort)
132
- : config.reasoningEffort;
124
+ const resolvedEffort = platformDefaults.thinkingEffort ?? config.reasoningEffort;
133
125
  if (platformDefaults.model)
134
126
  agentLog.info(
135
- `platform config: model=${platformDefaults.model} → resolved=${resolvedModel ?? 'cli-default'} (${platformModelOverride ? 'platform-managed' : 'floor/self'})`,
127
+ `platform config: model=${platformDefaults.model} → resolved=${resolvedModel ?? 'cli-default'} (${platformModelOverride ? 'pin/override' : 'floor'})`,
136
128
  );
137
129
  if (platformDefaults.thinkingEffort)
138
- agentLog.info(
139
- `platform config: reasoning_effort=${platformDefaults.thinkingEffort} (${platformModelOverride ? 'applied' : 'ignored, model_management=self'})`,
140
- );
130
+ agentLog.info(`platform config: reasoning_effort=${platformDefaults.thinkingEffort}`);
141
131
 
142
132
  const adapter = new CodexAppServerAdapter({
143
133
  codexBin: config.codexBin,
@@ -153,6 +143,35 @@ async function main() {
153
143
  useParallProvider,
154
144
  });
155
145
 
146
+ // Shared by onConfigUpdate + onSessionReady. /agents/me is only consumed as
147
+ // deriveModelIsPin's legacy fallback when the server omits model_is_pin
148
+ // (old server) — skip that round trip otherwise.
149
+ const refreshPlatformConfig = async () => {
150
+ const updated = await configMgr.fetch();
151
+ let refreshedProfile:
152
+ | Awaited<ReturnType<typeof getAgentMeWithLegacyFallback>>['agent_profile']
153
+ | undefined;
154
+ if (updated.modelIsPin === undefined) {
155
+ try {
156
+ refreshedProfile = (await getAgentMeWithLegacyFallback(client, config.orgId))
157
+ .agent_profile;
158
+ } catch (err) {
159
+ // configMgr.fetch() degrades to cache on failure; mirror that for the
160
+ // legacy fallback so a transient /agents/me error doesn't reject this
161
+ // config-refresh callback. No profile → deriveModelIsPin treats the
162
+ // delivered model as a floor (safe default).
163
+ agentLog.warn(
164
+ `platform config refresh: legacy /agents/me fallback failed: ${String(err)}`,
165
+ );
166
+ }
167
+ }
168
+ const isPin = deriveModelIsPin(updated, refreshedProfile);
169
+ adapter.updateConfig({
170
+ model: resolveRuntimeModel(isPin, updated.model, config.model) ?? null,
171
+ reasoningEffort: updated.thinkingEffort ?? config.reasoningEffort ?? null,
172
+ });
173
+ };
174
+
156
175
  const gateway = new ParallAgentGateway({
157
176
  accountId: agentUserId,
158
177
  client,
@@ -182,30 +201,8 @@ async function main() {
182
201
  contextFilePathForSession(config.stateDir, sessionKey),
183
202
  stepIdFilePathForSession: (sessionKey) =>
184
203
  stepIdFilePathForSession(config.stateDir, sessionKey),
185
- onConfigUpdate: async () => {
186
- const refreshed = await getAgentMeWithLegacyFallback(client, config.orgId);
187
- platformManaged = isPlatformManagedProfile(refreshed.agent_profile);
188
- platformModelOverride = isPlatformModelOverride(refreshed.agent_profile);
189
- const updated = await configMgr.fetch();
190
- adapter.updateConfig({
191
- model: resolveRuntimeModel(platformModelOverride, updated.model, config.model) ?? null,
192
- reasoningEffort: platformManaged
193
- ? (updated.thinkingEffort ?? config.reasoningEffort)
194
- : (config.reasoningEffort ?? null),
195
- });
196
- },
197
- onSessionReady: async () => {
198
- const refreshed = await getAgentMeWithLegacyFallback(client, config.orgId);
199
- platformManaged = isPlatformManagedProfile(refreshed.agent_profile);
200
- platformModelOverride = isPlatformModelOverride(refreshed.agent_profile);
201
- const updated = await configMgr.fetch();
202
- adapter.updateConfig({
203
- model: resolveRuntimeModel(platformModelOverride, updated.model, config.model) ?? null,
204
- reasoningEffort: platformManaged
205
- ? (updated.thinkingEffort ?? config.reasoningEffort)
206
- : (config.reasoningEffort ?? null),
207
- });
208
- },
204
+ onConfigUpdate: refreshPlatformConfig,
205
+ onSessionReady: refreshPlatformConfig,
209
206
  onNewSession: () => {
210
207
  sessionManager.clearMainThread();
211
208
  },