@parall/codex-agent 1.49.0 → 1.50.1
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.
- package/dist/index.js +37 -25
- package/package.json +4 -4
- package/src/index.ts +42 -27
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, capabilityBinDir, configureHttpKeepAlive, createPlatformConfigManager, createLogger, createOtelLogger, childLogger, deriveModelIsPin, materializeChannelCapabilities, resolveRuntimeModel, parseShutdownDeadlineMs, parseForkDeadlineMs, parseDispatchDeadlineMs, parseProviderConfig, clearAllProviderCreds, llmSource, initAgentTelemetry, } from '@parall/agent-core';
|
|
3
|
+
import { ParallAgentGateway, capabilityBinDir, configureHttpKeepAlive, createPlatformConfigManager, createLogger, createOtelLogger, childLogger, deriveModelIsPin, materializeChannelCapabilities, resolveRuntimeModel, parseShutdownDeadlineMs, parseForkDeadlineMs, parseDispatchDeadlineMs, parseProviderConfig, clearAllProviderCreds, llmSource, identityFromMe, initAgentTelemetry, } from '@parall/agent-core';
|
|
4
4
|
import { ApiError, ParallClient, ParallWs } from '@parall/sdk';
|
|
5
5
|
import { buildCodexRuntimeKey, contextFilePathForSession, dispatchContextDirPath, resolveCodexAgentConfig, resolveWsUrl, sessionStateFilePathForRuntime, stepIdFilePathForSession, } from './config.js';
|
|
6
6
|
import { CodexAppServerAdapter } from './dispatch.js';
|
|
@@ -17,7 +17,7 @@ async function getAgentMeWithLegacyFallback(client, orgId) {
|
|
|
17
17
|
throw err;
|
|
18
18
|
}
|
|
19
19
|
const user = await client.getMe();
|
|
20
|
-
return { ...user, agent_profile: null };
|
|
20
|
+
return { ...user, agent_profile: null, public_profile: null };
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
function resolveProviderEnv() {
|
|
@@ -59,11 +59,14 @@ async function main() {
|
|
|
59
59
|
ensureParallProvider(config.codexHome, config.apiUrl, agentLog);
|
|
60
60
|
agentLog.info('parall custom provider configured (Responses API HTTP/SSE mode)');
|
|
61
61
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
// Mutable on purpose: refreshPlatformConfig refetches it (see
|
|
63
|
+
// identityFromMe) so profile edits reach the next activation.
|
|
64
|
+
let agentIdentity = identityFromMe(me);
|
|
65
|
+
let lastIdentitySnapshot = JSON.stringify(agentIdentity);
|
|
66
|
+
// Last successful /agents/me profile — deriveModelIsPin's legacy fallback
|
|
67
|
+
// (old servers omit model_is_pin) must not flip a pinned model to floor
|
|
68
|
+
// just because one refresh round-trip failed.
|
|
69
|
+
let lastKnownAgentProfile = me.agent_profile;
|
|
67
70
|
const runtimeKey = config.runtimeKey || buildCodexRuntimeKey(agentUserId);
|
|
68
71
|
const mainContextFilePath = contextFilePathForSession(config.stateDir, runtimeKey);
|
|
69
72
|
const sessionStateFilePath = sessionStateFilePathForRuntime(config.stateDir, runtimeKey);
|
|
@@ -126,26 +129,28 @@ async function main() {
|
|
|
126
129
|
capabilityBinDir: capabilityBinDir(config.stateDir),
|
|
127
130
|
developerInstructions,
|
|
128
131
|
});
|
|
129
|
-
// Shared by onConfigUpdate + onSessionReady.
|
|
130
|
-
// deriveModelIsPin's legacy fallback when the server omits model_is_pin
|
|
131
|
-
// (old server) — skip that round trip otherwise.
|
|
132
|
+
// Shared by onConfigUpdate + onSessionReady.
|
|
132
133
|
const refreshPlatformConfig = async () => {
|
|
133
134
|
const updated = await configMgr.fetch();
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
135
|
+
// Unconditional /agents/me refetch: identity (title / public
|
|
136
|
+
// description / private instructions) rides the same
|
|
137
|
+
// agent_config.update nudge as model config. Failure degrades to the
|
|
138
|
+
// last-known-good identity, mirroring configMgr.fetch()'s cache
|
|
139
|
+
// fallback, so a transient error never rejects this callback. No
|
|
140
|
+
// profile → deriveModelIsPin treats the delivered model as a floor
|
|
141
|
+
// (safe default).
|
|
142
|
+
let refreshedMe;
|
|
143
|
+
try {
|
|
144
|
+
refreshedMe = await getAgentMeWithLegacyFallback(client, config.orgId);
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
agentLog.warn(`platform config refresh: /agents/me refetch failed (keeping last-known identity): ${String(err)}`);
|
|
148
|
+
}
|
|
149
|
+
if (refreshedMe) {
|
|
150
|
+
agentIdentity = identityFromMe(refreshedMe);
|
|
151
|
+
lastKnownAgentProfile = refreshedMe.agent_profile;
|
|
147
152
|
}
|
|
148
|
-
const isPin = deriveModelIsPin(updated,
|
|
153
|
+
const isPin = deriveModelIsPin(updated, lastKnownAgentProfile);
|
|
149
154
|
adapter.updateConfig({
|
|
150
155
|
model: resolveRuntimeModel(isPin, updated.model, config.model) ?? null,
|
|
151
156
|
reasoningEffort: updated.thinkingEffort ?? config.reasoningEffort ?? null,
|
|
@@ -175,8 +180,15 @@ async function main() {
|
|
|
175
180
|
promptWritten = false;
|
|
176
181
|
agentLog.warn(`system prompt refresh write failed (retrying next refresh): ${String(err)}`);
|
|
177
182
|
}
|
|
178
|
-
|
|
183
|
+
// Identity changes ride the same lazy-restart mechanism as capability
|
|
184
|
+
// fragments: the next fresh-process thread/resume applies the rebuilt
|
|
185
|
+
// developerInstructions, and the adapter compacts so the model-visible
|
|
186
|
+
// context converges (two-plane semantics: src/instructions-refresh.ts).
|
|
187
|
+
const identitySnapshot = JSON.stringify(agentIdentity);
|
|
188
|
+
if (promptWritten &&
|
|
189
|
+
(joinedFragments !== lastCapabilityFragments || identitySnapshot !== lastIdentitySnapshot)) {
|
|
179
190
|
lastCapabilityFragments = joinedFragments;
|
|
191
|
+
lastIdentitySnapshot = identitySnapshot;
|
|
180
192
|
adapter.requestProcessRestart();
|
|
181
193
|
}
|
|
182
194
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/codex-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.50.1",
|
|
4
4
|
"description": "Codex CLI bridge runtime for self-hosted Parall agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"src"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@parall/
|
|
29
|
-
"@parall/
|
|
30
|
-
"@parall/
|
|
28
|
+
"@parall/cli": "1.50.1",
|
|
29
|
+
"@parall/sdk": "1.50.1",
|
|
30
|
+
"@parall/agent-core": "1.50.1"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^22.0.0",
|
package/src/index.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
parseProviderConfig,
|
|
19
19
|
clearAllProviderCreds,
|
|
20
20
|
llmSource,
|
|
21
|
+
identityFromMe,
|
|
21
22
|
initAgentTelemetry,
|
|
22
23
|
} from '@parall/agent-core';
|
|
23
24
|
import { ApiError, ParallClient, ParallWs } from '@parall/sdk';
|
|
@@ -50,10 +51,12 @@ async function getAgentMeWithLegacyFallback(client: ParallClient, orgId: string)
|
|
|
50
51
|
throw err;
|
|
51
52
|
}
|
|
52
53
|
const user = await client.getMe();
|
|
53
|
-
return { ...user, agent_profile: null };
|
|
54
|
+
return { ...user, agent_profile: null, public_profile: null };
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
|
|
58
|
+
type AgentMe = Awaited<ReturnType<typeof getAgentMeWithLegacyFallback>>;
|
|
59
|
+
|
|
57
60
|
function resolveProviderEnv(): void {
|
|
58
61
|
const pc = parseProviderConfig(process.env);
|
|
59
62
|
if (!pc) return;
|
|
@@ -92,11 +95,14 @@ async function main() {
|
|
|
92
95
|
ensureParallProvider(config.codexHome, config.apiUrl, agentLog);
|
|
93
96
|
agentLog.info('parall custom provider configured (Responses API HTTP/SSE mode)');
|
|
94
97
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
// Mutable on purpose: refreshPlatformConfig refetches it (see
|
|
99
|
+
// identityFromMe) so profile edits reach the next activation.
|
|
100
|
+
let agentIdentity = identityFromMe(me);
|
|
101
|
+
let lastIdentitySnapshot = JSON.stringify(agentIdentity);
|
|
102
|
+
// Last successful /agents/me profile — deriveModelIsPin's legacy fallback
|
|
103
|
+
// (old servers omit model_is_pin) must not flip a pinned model to floor
|
|
104
|
+
// just because one refresh round-trip failed.
|
|
105
|
+
let lastKnownAgentProfile = me.agent_profile;
|
|
100
106
|
const runtimeKey = config.runtimeKey || buildCodexRuntimeKey(agentUserId);
|
|
101
107
|
const mainContextFilePath = contextFilePathForSession(config.stateDir, runtimeKey);
|
|
102
108
|
const sessionStateFilePath = sessionStateFilePathForRuntime(config.stateDir, runtimeKey);
|
|
@@ -174,29 +180,29 @@ async function main() {
|
|
|
174
180
|
developerInstructions,
|
|
175
181
|
});
|
|
176
182
|
|
|
177
|
-
// Shared by onConfigUpdate + onSessionReady.
|
|
178
|
-
// deriveModelIsPin's legacy fallback when the server omits model_is_pin
|
|
179
|
-
// (old server) — skip that round trip otherwise.
|
|
183
|
+
// Shared by onConfigUpdate + onSessionReady.
|
|
180
184
|
const refreshPlatformConfig = async () => {
|
|
181
185
|
const updated = await configMgr.fetch();
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
186
|
+
// Unconditional /agents/me refetch: identity (title / public
|
|
187
|
+
// description / private instructions) rides the same
|
|
188
|
+
// agent_config.update nudge as model config. Failure degrades to the
|
|
189
|
+
// last-known-good identity, mirroring configMgr.fetch()'s cache
|
|
190
|
+
// fallback, so a transient error never rejects this callback. No
|
|
191
|
+
// profile → deriveModelIsPin treats the delivered model as a floor
|
|
192
|
+
// (safe default).
|
|
193
|
+
let refreshedMe: AgentMe | undefined;
|
|
194
|
+
try {
|
|
195
|
+
refreshedMe = await getAgentMeWithLegacyFallback(client, config.orgId);
|
|
196
|
+
} catch (err) {
|
|
197
|
+
agentLog.warn(
|
|
198
|
+
`platform config refresh: /agents/me refetch failed (keeping last-known identity): ${String(err)}`,
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
if (refreshedMe) {
|
|
202
|
+
agentIdentity = identityFromMe(refreshedMe);
|
|
203
|
+
lastKnownAgentProfile = refreshedMe.agent_profile;
|
|
198
204
|
}
|
|
199
|
-
const isPin = deriveModelIsPin(updated,
|
|
205
|
+
const isPin = deriveModelIsPin(updated, lastKnownAgentProfile);
|
|
200
206
|
adapter.updateConfig({
|
|
201
207
|
model: resolveRuntimeModel(isPin, updated.model, config.model) ?? null,
|
|
202
208
|
reasoningEffort: updated.thinkingEffort ?? config.reasoningEffort ?? null,
|
|
@@ -229,8 +235,17 @@ async function main() {
|
|
|
229
235
|
promptWritten = false;
|
|
230
236
|
agentLog.warn(`system prompt refresh write failed (retrying next refresh): ${String(err)}`);
|
|
231
237
|
}
|
|
232
|
-
|
|
238
|
+
// Identity changes ride the same lazy-restart mechanism as capability
|
|
239
|
+
// fragments: the next fresh-process thread/resume applies the rebuilt
|
|
240
|
+
// developerInstructions, and the adapter compacts so the model-visible
|
|
241
|
+
// context converges (two-plane semantics: src/instructions-refresh.ts).
|
|
242
|
+
const identitySnapshot = JSON.stringify(agentIdentity);
|
|
243
|
+
if (
|
|
244
|
+
promptWritten &&
|
|
245
|
+
(joinedFragments !== lastCapabilityFragments || identitySnapshot !== lastIdentitySnapshot)
|
|
246
|
+
) {
|
|
233
247
|
lastCapabilityFragments = joinedFragments;
|
|
248
|
+
lastIdentitySnapshot = identitySnapshot;
|
|
234
249
|
adapter.requestProcessRestart();
|
|
235
250
|
}
|
|
236
251
|
};
|