@parall/claude-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 +36 -22
- package/package.json +4 -4
- package/src/index.ts +41 -24
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 { buildClaudeRuntimeKey, contextFilePathForSession, dispatchContextDirPath, resolveClaudeAgentConfig, resolveWsUrl, sessionStateFilePathForRuntime, stepIdFilePathForSession, } from './config.js';
|
|
6
6
|
import { ClaudeCodeAdapter } 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() {
|
|
@@ -65,11 +65,14 @@ async function main() {
|
|
|
65
65
|
activeLog = agentLog;
|
|
66
66
|
// Shared by the initial workspace write and the config-refresh rewrite of
|
|
67
67
|
// .parall/system-prompt.md — both need identity + capability fragments.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
// Mutable on purpose: refreshPlatformConfig refetches it (see
|
|
69
|
+
// identityFromMe) so profile edits reach the next activation.
|
|
70
|
+
let agentIdentity = identityFromMe(me);
|
|
71
|
+
let lastIdentitySnapshot = JSON.stringify(agentIdentity);
|
|
72
|
+
// Last successful /agents/me profile — deriveModelIsPin's legacy fallback
|
|
73
|
+
// (old servers omit model_is_pin) must not flip a pinned model to floor
|
|
74
|
+
// just because one refresh round-trip failed.
|
|
75
|
+
let lastKnownAgentProfile = me.agent_profile;
|
|
73
76
|
const runtimeKey = config.runtimeKey || buildClaudeRuntimeKey(agentUserId);
|
|
74
77
|
const sessionStateFilePath = sessionStateFilePathForRuntime(config.stateDir, runtimeKey);
|
|
75
78
|
const sessionManager = new ClaudeSessionManager(runtimeKey, sessionStateFilePath, agentLog);
|
|
@@ -147,21 +150,25 @@ async function main() {
|
|
|
147
150
|
// (old server) — skip that round trip otherwise.
|
|
148
151
|
const refreshPlatformConfig = async () => {
|
|
149
152
|
const updated = await configMgr.fetch();
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
153
|
+
// Unconditional /agents/me refetch: identity (title / public
|
|
154
|
+
// description / private instructions) rides the same
|
|
155
|
+
// agent_config.update nudge as model config. Failure degrades to the
|
|
156
|
+
// last-known-good identity, mirroring configMgr.fetch()'s cache
|
|
157
|
+
// fallback, so a transient error never rejects this callback. No
|
|
158
|
+
// profile → deriveModelIsPin treats the delivered model as a floor
|
|
159
|
+
// (safe default).
|
|
160
|
+
let refreshedMe;
|
|
161
|
+
try {
|
|
162
|
+
refreshedMe = await getAgentMeWithLegacyFallback(client, config.orgId);
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
agentLog.warn(`platform config refresh: /agents/me refetch failed (keeping last-known identity): ${String(err)}`);
|
|
166
|
+
}
|
|
167
|
+
if (refreshedMe) {
|
|
168
|
+
agentIdentity = identityFromMe(refreshedMe);
|
|
169
|
+
lastKnownAgentProfile = refreshedMe.agent_profile;
|
|
163
170
|
}
|
|
164
|
-
const isPin = deriveModelIsPin(updated,
|
|
171
|
+
const isPin = deriveModelIsPin(updated, lastKnownAgentProfile);
|
|
165
172
|
const localEffort = process.env.CLAUDE_CODE_EFFORT_LEVEL?.trim() || null;
|
|
166
173
|
adapter.updateConfig({
|
|
167
174
|
model: resolveRuntimeModel(isPin, updated.model, config.model) ?? null,
|
|
@@ -196,8 +203,15 @@ async function main() {
|
|
|
196
203
|
promptWritten = false;
|
|
197
204
|
agentLog.warn(`system prompt refresh write failed (retrying next refresh): ${String(err)}`);
|
|
198
205
|
}
|
|
199
|
-
|
|
206
|
+
// Identity changes ride the same lazy-respawn mechanism as capability
|
|
207
|
+
// fragments: the live child loaded its prompt at spawn, so a changed
|
|
208
|
+
// identity marks it for an out-of-turn --resume respawn and the next
|
|
209
|
+
// activation runs with the new prompt.
|
|
210
|
+
const identitySnapshot = JSON.stringify(agentIdentity);
|
|
211
|
+
if (promptWritten &&
|
|
212
|
+
(joinedFragments !== lastCapabilityFragments || identitySnapshot !== lastIdentitySnapshot)) {
|
|
200
213
|
lastCapabilityFragments = joinedFragments;
|
|
214
|
+
lastIdentitySnapshot = identitySnapshot;
|
|
201
215
|
adapter.requestProcessRestart();
|
|
202
216
|
}
|
|
203
217
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/claude-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.50.1",
|
|
4
4
|
"description": "Claude Code 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/agent-core": "1.
|
|
29
|
-
"@parall/cli": "1.
|
|
30
|
-
"@parall/sdk": "1.
|
|
28
|
+
"@parall/agent-core": "1.50.1",
|
|
29
|
+
"@parall/cli": "1.50.1",
|
|
30
|
+
"@parall/sdk": "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';
|
|
@@ -45,10 +46,12 @@ async function getAgentMeWithLegacyFallback(client: ParallClient, orgId: string)
|
|
|
45
46
|
throw err;
|
|
46
47
|
}
|
|
47
48
|
const user = await client.getMe();
|
|
48
|
-
return { ...user, agent_profile: null };
|
|
49
|
+
return { ...user, agent_profile: null, public_profile: null };
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
type AgentMe = Awaited<ReturnType<typeof getAgentMeWithLegacyFallback>>;
|
|
54
|
+
|
|
52
55
|
function resolveProviderEnv(): void {
|
|
53
56
|
const pc = parseProviderConfig(process.env);
|
|
54
57
|
if (!pc) return;
|
|
@@ -97,11 +100,14 @@ async function main() {
|
|
|
97
100
|
activeLog = agentLog;
|
|
98
101
|
// Shared by the initial workspace write and the config-refresh rewrite of
|
|
99
102
|
// .parall/system-prompt.md — both need identity + capability fragments.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
// Mutable on purpose: refreshPlatformConfig refetches it (see
|
|
104
|
+
// identityFromMe) so profile edits reach the next activation.
|
|
105
|
+
let agentIdentity = identityFromMe(me);
|
|
106
|
+
let lastIdentitySnapshot = JSON.stringify(agentIdentity);
|
|
107
|
+
// Last successful /agents/me profile — deriveModelIsPin's legacy fallback
|
|
108
|
+
// (old servers omit model_is_pin) must not flip a pinned model to floor
|
|
109
|
+
// just because one refresh round-trip failed.
|
|
110
|
+
let lastKnownAgentProfile = me.agent_profile;
|
|
105
111
|
const runtimeKey = config.runtimeKey || buildClaudeRuntimeKey(agentUserId);
|
|
106
112
|
const sessionStateFilePath = sessionStateFilePathForRuntime(config.stateDir, runtimeKey);
|
|
107
113
|
const sessionManager = new ClaudeSessionManager(runtimeKey, sessionStateFilePath, agentLog);
|
|
@@ -192,24 +198,26 @@ async function main() {
|
|
|
192
198
|
// (old server) — skip that round trip otherwise.
|
|
193
199
|
const refreshPlatformConfig = async () => {
|
|
194
200
|
const updated = await configMgr.fetch();
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
201
|
+
// Unconditional /agents/me refetch: identity (title / public
|
|
202
|
+
// description / private instructions) rides the same
|
|
203
|
+
// agent_config.update nudge as model config. Failure degrades to the
|
|
204
|
+
// last-known-good identity, mirroring configMgr.fetch()'s cache
|
|
205
|
+
// fallback, so a transient error never rejects this callback. No
|
|
206
|
+
// profile → deriveModelIsPin treats the delivered model as a floor
|
|
207
|
+
// (safe default).
|
|
208
|
+
let refreshedMe: AgentMe | undefined;
|
|
209
|
+
try {
|
|
210
|
+
refreshedMe = await getAgentMeWithLegacyFallback(client, config.orgId);
|
|
211
|
+
} catch (err) {
|
|
212
|
+
agentLog.warn(
|
|
213
|
+
`platform config refresh: /agents/me refetch failed (keeping last-known identity): ${String(err)}`,
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
if (refreshedMe) {
|
|
217
|
+
agentIdentity = identityFromMe(refreshedMe);
|
|
218
|
+
lastKnownAgentProfile = refreshedMe.agent_profile;
|
|
211
219
|
}
|
|
212
|
-
const isPin = deriveModelIsPin(updated,
|
|
220
|
+
const isPin = deriveModelIsPin(updated, lastKnownAgentProfile);
|
|
213
221
|
const localEffort = process.env.CLAUDE_CODE_EFFORT_LEVEL?.trim() || null;
|
|
214
222
|
adapter.updateConfig({
|
|
215
223
|
model: resolveRuntimeModel(isPin, updated.model, config.model) ?? null,
|
|
@@ -243,8 +251,17 @@ async function main() {
|
|
|
243
251
|
promptWritten = false;
|
|
244
252
|
agentLog.warn(`system prompt refresh write failed (retrying next refresh): ${String(err)}`);
|
|
245
253
|
}
|
|
246
|
-
|
|
254
|
+
// Identity changes ride the same lazy-respawn mechanism as capability
|
|
255
|
+
// fragments: the live child loaded its prompt at spawn, so a changed
|
|
256
|
+
// identity marks it for an out-of-turn --resume respawn and the next
|
|
257
|
+
// activation runs with the new prompt.
|
|
258
|
+
const identitySnapshot = JSON.stringify(agentIdentity);
|
|
259
|
+
if (
|
|
260
|
+
promptWritten &&
|
|
261
|
+
(joinedFragments !== lastCapabilityFragments || identitySnapshot !== lastIdentitySnapshot)
|
|
262
|
+
) {
|
|
247
263
|
lastCapabilityFragments = joinedFragments;
|
|
264
|
+
lastIdentitySnapshot = identitySnapshot;
|
|
248
265
|
adapter.requestProcessRestart();
|
|
249
266
|
}
|
|
250
267
|
};
|