@parall/claude-agent 1.61.0 → 1.63.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.
- package/dist/dispatch.d.ts +2 -6
- package/dist/dispatch.d.ts.map +1 -1
- package/dist/dispatch.js +7 -3
- package/dist/index.js +5 -2
- package/dist/input-lifecycle.d.ts +3 -3
- package/dist/input-lifecycle.d.ts.map +1 -1
- package/dist/input-lifecycle.js +13 -6
- package/dist/process-pump.d.ts.map +1 -1
- package/dist/process-pump.js +5 -2
- package/package.json +4 -4
- package/src/dispatch.ts +9 -9
- package/src/index.ts +5 -1
- package/src/input-lifecycle.ts +21 -6
- package/src/process-pump.ts +5 -2
package/dist/dispatch.d.ts
CHANGED
|
@@ -18,12 +18,8 @@ type ClaudeCodeAdapterOptions = Pick<ClaudeAgentConfig, 'additionalDirs' | 'allo
|
|
|
18
18
|
/** @deprecated Use contextFilePathForSession. */
|
|
19
19
|
stepIdFilePathForSession?: (sessionKey: string) => string;
|
|
20
20
|
/**
|
|
21
|
-
* PRLL_CONTEXT_DIR root
|
|
22
|
-
*
|
|
23
|
-
* subprocess env is built ONCE from the placeholder context, so a value
|
|
24
|
-
* only present on per-dispatch DispatchContexts would never reach the
|
|
25
|
-
* CLI and every reply would silently lose its lane binding (turns would
|
|
26
|
-
* resolve no_action instead of reply-effect dedupe).
|
|
21
|
+
* Bridge-static PRLL_CONTEXT_DIR root: a value only in per-dispatch context
|
|
22
|
+
* never reaches the long-lived CLI, so replies lose their lane binding.
|
|
27
23
|
*/
|
|
28
24
|
contextDirPath?: string;
|
|
29
25
|
/**
|
package/dist/dispatch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EACf,WAAW,EACX,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACb,MAAM,oBAAoB,CAAC;AAQ5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAA4B,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAErF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,KAAK,wBAAwB,GAAG,IAAI,CAClC,iBAAiB,EACf,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,oBAAoB,GACpB,WAAW,GACX,YAAY,GACZ,iBAAiB,GACjB,OAAO,GACP,gBAAgB,GAChB,cAAc,CACjB,GAAG;IACF,cAAc,EAAE,oBAAoB,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3D,iDAAiD;IACjD,wBAAwB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1D
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"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"}
|
package/dist/dispatch.js
CHANGED
|
@@ -282,7 +282,10 @@ export class ClaudeCodeAdapter {
|
|
|
282
282
|
}
|
|
283
283
|
catch (err) {
|
|
284
284
|
try {
|
|
285
|
-
await lifecycle?.update('failed'
|
|
285
|
+
await lifecycle?.update('failed', {
|
|
286
|
+
outcomeClass: 'runtime_crash',
|
|
287
|
+
detail: `Claude spawn failed: ${String(err)}`,
|
|
288
|
+
});
|
|
286
289
|
}
|
|
287
290
|
catch (reportErr) {
|
|
288
291
|
log?.warn?.(`failed to report rejected Claude input as failed: ${String(reportErr)}`);
|
|
@@ -297,7 +300,7 @@ export class ClaudeCodeAdapter {
|
|
|
297
300
|
this.writeUserMessage(state.handle, promptBody, delivery.commandUuid);
|
|
298
301
|
}
|
|
299
302
|
catch (err) {
|
|
300
|
-
await state.inputs.failBestEffort(delivery, log);
|
|
303
|
+
await state.inputs.failBestEffort(delivery, log, `Claude stdin write failed: ${String(err)}`);
|
|
301
304
|
state.inputs.remove(delivery);
|
|
302
305
|
yield { type: 'error', message: `Claude stdin write failed: ${String(err)}` };
|
|
303
306
|
this.killProcess(sessionKey, state);
|
|
@@ -546,7 +549,8 @@ export class ClaudeCodeAdapter {
|
|
|
546
549
|
proc.stderr.on('data', (chunk) => {
|
|
547
550
|
stderrChunks.push(chunk.toString());
|
|
548
551
|
});
|
|
549
|
-
proc.stdin.on('error', () => {
|
|
552
|
+
proc.stdin.on('error', (err) => {
|
|
553
|
+
stderrChunks.push(`Claude stdin failed: ${String(err)}\n`);
|
|
550
554
|
proc.stdin.destroy();
|
|
551
555
|
if (proc.exitCode === null && proc.signalCode === null) {
|
|
552
556
|
if (!IS_WIN32 || !proc.pid || !killWin32Tree(proc.pid)) {
|
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 { capabilityBinDir, childLogger, clearAllProviderCreds, configureHttpKeepAlive, createLogger, createOtelLogger, createPlatformConfigManager, deriveModelIsPin, identityFromMe, initAgentTelemetry, llmSource, resolveServiceVersion, materializeChannelCapabilities, ParallAgentGateway, parseDispatchDeadlineMs, parseForkDeadlineMs, parseProviderConfig, parseShutdownDeadlineMs, resolveRuntimeContextWindow, resolveRuntimeMaxTokens, resolveRuntimeModel, } from '@parall/agent-core';
|
|
3
|
+
import { capabilityBinDir, childLogger, clearAllProviderCreds, configureHttpKeepAlive, createLogger, createOtelLogger, createPlatformConfigManager, deriveModelIsPin, identityFromMe, initAgentTelemetry, llmSource, resolveServiceVersion, materializeChannelCapabilities, ParallAgentGateway, parseDispatchDeadlineMs, parseForkDeadlineMs, parseProviderConfig, parseShutdownDeadlineMs, resolveRuntimeContextWindow, resolveRuntimeMaxTokens, resolveRuntimeModel, traceContextHeaders, } 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';
|
|
@@ -44,10 +44,11 @@ function resolveProviderEnv() {
|
|
|
44
44
|
async function main() {
|
|
45
45
|
// Before any fetch: long-lived HTTP connections for every bridge→api call.
|
|
46
46
|
configureHttpKeepAlive();
|
|
47
|
+
const serviceVersion = resolveServiceVersion(import.meta.url);
|
|
47
48
|
const telemetry = await initAgentTelemetry('parall-claude-agent', 'claude-code', {
|
|
48
49
|
apiUrl: process.env.PRLL_API_URL,
|
|
49
50
|
apiKey: process.env.PRLL_API_KEY,
|
|
50
|
-
serviceVersion
|
|
51
|
+
serviceVersion,
|
|
51
52
|
});
|
|
52
53
|
activeLog = createOtelLogger('agent', 'claude-agent');
|
|
53
54
|
try {
|
|
@@ -63,6 +64,7 @@ async function main() {
|
|
|
63
64
|
baseUrl: config.apiUrl,
|
|
64
65
|
token: config.apiKey,
|
|
65
66
|
swimlaneName: config.swimlaneName,
|
|
67
|
+
getRequestHeaders: traceContextHeaders,
|
|
66
68
|
});
|
|
67
69
|
const me = await getAgentMeWithLegacyFallback(client, config.orgId);
|
|
68
70
|
const agentUserId = me.id;
|
|
@@ -243,6 +245,7 @@ async function main() {
|
|
|
243
245
|
},
|
|
244
246
|
agentUserId,
|
|
245
247
|
runtimeType: 'claude-code',
|
|
248
|
+
runtimeVersion: serviceVersion,
|
|
246
249
|
runtimeKey,
|
|
247
250
|
runtimeRef: {
|
|
248
251
|
hostname: os.hostname(),
|
|
@@ -63,8 +63,8 @@ export declare class ClaudeInputRegistry {
|
|
|
63
63
|
*/
|
|
64
64
|
discardBookkeeping(deliveryKey: string): void;
|
|
65
65
|
apply(delivery: ClaudeInputDelivery, state: 'queued' | 'started' | 'completed' | 'cancelled' | 'discarded'): Promise<void>;
|
|
66
|
-
fail(delivery: ClaudeInputDelivery): Promise<void>;
|
|
67
|
-
failBestEffort(delivery: ClaudeInputDelivery, log?: GatewayLogger): Promise<void>;
|
|
68
|
-
failAllBestEffort(log?: GatewayLogger): Promise<void>;
|
|
66
|
+
fail(delivery: ClaudeInputDelivery, detail?: string): Promise<void>;
|
|
67
|
+
failBestEffort(delivery: ClaudeInputDelivery, log?: GatewayLogger, detail?: string): Promise<void>;
|
|
68
|
+
failAllBestEffort(log?: GatewayLogger, detail?: string): Promise<void>;
|
|
69
69
|
}
|
|
70
70
|
//# sourceMappingURL=input-lifecycle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-lifecycle.d.ts","sourceRoot":"","sources":["../src/input-lifecycle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"input-lifecycle.d.ts","sourceRoot":"","sources":["../src/input-lifecycle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEnG,OAAO,EACL,KAAK,cAAc,EAGnB,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC9C,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,YAAY,EAAE,OAAO,CAAC;IACtB,kFAAkF;IAClF,IAAI,EAAE,cAAc,CAAC;IACrB,uEAAuE;IACvE,QAAQ,EAAE,YAAY,CAAC;IACvB,6FAA6F;IAC7F,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,8DAA8D;IAC9D,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF;;;;GAIG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0C;IAChE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0C;IAEpE,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;IAI9D,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;IAIlE,eAAe,CAAC,gBAAgB,EAAE,MAAM,EAAE,GAAG,mBAAmB,GAAG,SAAS;IAU5E,MAAM,IAAI,gBAAgB,CAAC,mBAAmB,CAAC;IAI/C,oBAAoB,IAAI,OAAO;IAI/B;;;;;;;;;OASG;IACH,sBAAsB,IAAI,OAAO;IAIjC,QAAQ,CACN,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,sBAAsB,GAAG,SAAS,EAC7C,QAAQ,EAAE,OAAO,EACjB,YAAY,CAAC,EAAE,MAAM,IAAI,EACzB,GAAG,CAAC,EAAE,aAAa,GAClB,mBAAmB;IAsBtB,MAAM,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAY3C;;;;;;;;OAQG;IACH,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAOvC,KAAK,CACT,QAAQ,EAAE,mBAAmB,EAC7B,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,GACpE,OAAO,CAAC,IAAI,CAAC;IA0BV,IAAI,CAAC,QAAQ,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BnE,cAAc,CAClB,QAAQ,EAAE,mBAAmB,EAC7B,GAAG,CAAC,EAAE,aAAa,EACnB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC;IAUV,iBAAiB,CAAC,GAAG,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAO7E"}
|
package/dist/input-lifecycle.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { classifyClaudeTurn } from './turn-outcome.js';
|
|
2
3
|
import { newTurnEvidence, newTurnSink, } from './turn-sink.js';
|
|
3
4
|
/**
|
|
4
5
|
* Per-process registry that maps Parall WorkItem batches to Claude stdin
|
|
@@ -116,7 +117,7 @@ export class ClaudeInputRegistry {
|
|
|
116
117
|
if (delivery.drained)
|
|
117
118
|
this.remove(delivery);
|
|
118
119
|
}
|
|
119
|
-
async fail(delivery) {
|
|
120
|
+
async fail(delivery, detail) {
|
|
120
121
|
if (delivery.terminal)
|
|
121
122
|
return;
|
|
122
123
|
if (delivery.suppressFailReport) {
|
|
@@ -127,7 +128,13 @@ export class ClaudeInputRegistry {
|
|
|
127
128
|
}
|
|
128
129
|
try {
|
|
129
130
|
if (delivery.reportedState !== 'failed') {
|
|
130
|
-
const
|
|
131
|
+
const classified = classifyClaudeTurn(delivery.evidence.lastResultMeta, delivery.evidence.noticeTexts);
|
|
132
|
+
const result = await delivery.lifecycle?.update('failed', {
|
|
133
|
+
outcomeClass: classified.outcome === 'ok' || classified.outcome === 'usage_limit'
|
|
134
|
+
? 'runtime_crash'
|
|
135
|
+
: classified.outcome,
|
|
136
|
+
detail: detail ?? classified.detail ?? 'Claude input failed',
|
|
137
|
+
});
|
|
131
138
|
delivery.reportedState = 'failed';
|
|
132
139
|
delivery.terminal = result?.retry === false ? 'settled' : 'failed';
|
|
133
140
|
}
|
|
@@ -138,17 +145,17 @@ export class ClaudeInputRegistry {
|
|
|
138
145
|
this.remove(delivery);
|
|
139
146
|
}
|
|
140
147
|
}
|
|
141
|
-
async failBestEffort(delivery, log) {
|
|
148
|
+
async failBestEffort(delivery, log, detail) {
|
|
142
149
|
try {
|
|
143
|
-
await this.fail(delivery);
|
|
150
|
+
await this.fail(delivery, detail);
|
|
144
151
|
}
|
|
145
152
|
catch (err) {
|
|
146
153
|
log?.warn?.(`failed to report Claude input ${delivery.commandUuid} as failed: ${String(err)}`);
|
|
147
154
|
}
|
|
148
155
|
}
|
|
149
|
-
async failAllBestEffort(log) {
|
|
156
|
+
async failAllBestEffort(log, detail) {
|
|
150
157
|
await Promise.all([...this.byKey.values()]
|
|
151
158
|
.filter((delivery) => !delivery.terminal)
|
|
152
|
-
.map((delivery) => this.failBestEffort(delivery, log)));
|
|
159
|
+
.map((delivery) => this.failBestEffort(delivery, log, detail)));
|
|
153
160
|
}
|
|
154
161
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-pump.d.ts","sourceRoot":"","sources":["../src/process-pump.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"process-pump.d.ts","sourceRoot":"","sources":["../src/process-pump.ts"],"names":[],"mappings":"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"}
|
package/dist/process-pump.js
CHANGED
|
@@ -417,8 +417,11 @@ export class ClaudeProcessPump {
|
|
|
417
417
|
if (!delivery.terminal && settledAsLimit(delivery.evidence))
|
|
418
418
|
delivery.suppressFailReport = true;
|
|
419
419
|
}
|
|
420
|
-
|
|
421
|
-
for
|
|
420
|
+
// Failing removes drained deliveries from the registry. Their sinks must
|
|
421
|
+
// still receive EOF, or a startup failure waits for the dispatch timeout.
|
|
422
|
+
const deliveries = [...inputs.values()];
|
|
423
|
+
await inputs.failAllBestEffort(log, message);
|
|
424
|
+
for (const delivery of deliveries) {
|
|
422
425
|
delivery.sink.push({ kind: 'ended', reason: 'eof', message });
|
|
423
426
|
delivery.sink.close();
|
|
424
427
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/claude-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.63.0",
|
|
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.63.0",
|
|
29
|
+
"@parall/cli": "1.63.0",
|
|
30
|
+
"@parall/sdk": "1.63.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^22.0.0",
|
package/src/dispatch.ts
CHANGED
|
@@ -57,12 +57,8 @@ type ClaudeCodeAdapterOptions = Pick<
|
|
|
57
57
|
/** @deprecated Use contextFilePathForSession. */
|
|
58
58
|
stepIdFilePathForSession?: (sessionKey: string) => string;
|
|
59
59
|
/**
|
|
60
|
-
* PRLL_CONTEXT_DIR root
|
|
61
|
-
*
|
|
62
|
-
* subprocess env is built ONCE from the placeholder context, so a value
|
|
63
|
-
* only present on per-dispatch DispatchContexts would never reach the
|
|
64
|
-
* CLI and every reply would silently lose its lane binding (turns would
|
|
65
|
-
* resolve no_action instead of reply-effect dedupe).
|
|
60
|
+
* Bridge-static PRLL_CONTEXT_DIR root: a value only in per-dispatch context
|
|
61
|
+
* never reaches the long-lived CLI, so replies lose their lane binding.
|
|
66
62
|
*/
|
|
67
63
|
contextDirPath?: string;
|
|
68
64
|
/**
|
|
@@ -410,7 +406,10 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
|
|
|
410
406
|
state = this.ensureProcess(sessionKey, log);
|
|
411
407
|
} catch (err) {
|
|
412
408
|
try {
|
|
413
|
-
await lifecycle?.update('failed'
|
|
409
|
+
await lifecycle?.update('failed', {
|
|
410
|
+
outcomeClass: 'runtime_crash',
|
|
411
|
+
detail: `Claude spawn failed: ${String(err)}`,
|
|
412
|
+
});
|
|
414
413
|
} catch (reportErr) {
|
|
415
414
|
log?.warn?.(`failed to report rejected Claude input as failed: ${String(reportErr)}`);
|
|
416
415
|
}
|
|
@@ -423,7 +422,7 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
|
|
|
423
422
|
try {
|
|
424
423
|
this.writeUserMessage(state.handle, promptBody, delivery.commandUuid);
|
|
425
424
|
} catch (err) {
|
|
426
|
-
await state.inputs.failBestEffort(delivery, log);
|
|
425
|
+
await state.inputs.failBestEffort(delivery, log, `Claude stdin write failed: ${String(err)}`);
|
|
427
426
|
state.inputs.remove(delivery);
|
|
428
427
|
yield { type: 'error', message: `Claude stdin write failed: ${String(err)}` };
|
|
429
428
|
this.killProcess(sessionKey, state);
|
|
@@ -704,7 +703,8 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
|
|
|
704
703
|
proc.stderr.on('data', (chunk: Buffer) => {
|
|
705
704
|
stderrChunks.push(chunk.toString());
|
|
706
705
|
});
|
|
707
|
-
proc.stdin.on('error', () => {
|
|
706
|
+
proc.stdin.on('error', (err) => {
|
|
707
|
+
stderrChunks.push(`Claude stdin failed: ${String(err)}\n`);
|
|
708
708
|
proc.stdin.destroy();
|
|
709
709
|
if (proc.exitCode === null && proc.signalCode === null) {
|
|
710
710
|
if (!IS_WIN32 || !proc.pid || !killWin32Tree(proc.pid)) {
|
package/src/index.ts
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
resolveRuntimeContextWindow,
|
|
24
24
|
resolveRuntimeMaxTokens,
|
|
25
25
|
resolveRuntimeModel,
|
|
26
|
+
traceContextHeaders,
|
|
26
27
|
} from '@parall/agent-core';
|
|
27
28
|
import { ApiError, ParallClient, ParallWs } from '@parall/sdk';
|
|
28
29
|
import {
|
|
@@ -77,10 +78,11 @@ function resolveProviderEnv(): string {
|
|
|
77
78
|
async function main() {
|
|
78
79
|
// Before any fetch: long-lived HTTP connections for every bridge→api call.
|
|
79
80
|
configureHttpKeepAlive();
|
|
81
|
+
const serviceVersion = resolveServiceVersion(import.meta.url);
|
|
80
82
|
const telemetry = await initAgentTelemetry('parall-claude-agent', 'claude-code', {
|
|
81
83
|
apiUrl: process.env.PRLL_API_URL,
|
|
82
84
|
apiKey: process.env.PRLL_API_KEY,
|
|
83
|
-
serviceVersion
|
|
85
|
+
serviceVersion,
|
|
84
86
|
});
|
|
85
87
|
activeLog = createOtelLogger('agent', 'claude-agent');
|
|
86
88
|
try {
|
|
@@ -100,6 +102,7 @@ async function main() {
|
|
|
100
102
|
baseUrl: config.apiUrl,
|
|
101
103
|
token: config.apiKey,
|
|
102
104
|
swimlaneName: config.swimlaneName,
|
|
105
|
+
getRequestHeaders: traceContextHeaders,
|
|
103
106
|
});
|
|
104
107
|
|
|
105
108
|
const me = await getAgentMeWithLegacyFallback(client, config.orgId);
|
|
@@ -304,6 +307,7 @@ async function main() {
|
|
|
304
307
|
},
|
|
305
308
|
agentUserId,
|
|
306
309
|
runtimeType: 'claude-code',
|
|
310
|
+
runtimeVersion: serviceVersion,
|
|
307
311
|
runtimeKey,
|
|
308
312
|
runtimeRef: {
|
|
309
313
|
hostname: os.hostname(),
|
package/src/input-lifecycle.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import type { DispatchInputLifecycle, GatewayLogger, RuntimeInputState } from '@parall/agent-core';
|
|
3
|
+
import { classifyClaudeTurn } from './turn-outcome.js';
|
|
3
4
|
import {
|
|
4
5
|
type ClaudeTurnSink,
|
|
5
6
|
newTurnEvidence,
|
|
@@ -168,7 +169,7 @@ export class ClaudeInputRegistry {
|
|
|
168
169
|
if (delivery.drained) this.remove(delivery);
|
|
169
170
|
}
|
|
170
171
|
|
|
171
|
-
async fail(delivery: ClaudeInputDelivery): Promise<void> {
|
|
172
|
+
async fail(delivery: ClaudeInputDelivery, detail?: string): Promise<void> {
|
|
172
173
|
if (delivery.terminal) return;
|
|
173
174
|
if (delivery.suppressFailReport) {
|
|
174
175
|
delivery.terminal = 'settled';
|
|
@@ -177,7 +178,17 @@ export class ClaudeInputRegistry {
|
|
|
177
178
|
}
|
|
178
179
|
try {
|
|
179
180
|
if (delivery.reportedState !== 'failed') {
|
|
180
|
-
const
|
|
181
|
+
const classified = classifyClaudeTurn(
|
|
182
|
+
delivery.evidence.lastResultMeta,
|
|
183
|
+
delivery.evidence.noticeTexts,
|
|
184
|
+
);
|
|
185
|
+
const result = await delivery.lifecycle?.update('failed', {
|
|
186
|
+
outcomeClass:
|
|
187
|
+
classified.outcome === 'ok' || classified.outcome === 'usage_limit'
|
|
188
|
+
? 'runtime_crash'
|
|
189
|
+
: classified.outcome,
|
|
190
|
+
detail: detail ?? classified.detail ?? 'Claude input failed',
|
|
191
|
+
});
|
|
181
192
|
delivery.reportedState = 'failed';
|
|
182
193
|
delivery.terminal = result?.retry === false ? 'settled' : 'failed';
|
|
183
194
|
}
|
|
@@ -187,9 +198,13 @@ export class ClaudeInputRegistry {
|
|
|
187
198
|
}
|
|
188
199
|
}
|
|
189
200
|
|
|
190
|
-
async failBestEffort(
|
|
201
|
+
async failBestEffort(
|
|
202
|
+
delivery: ClaudeInputDelivery,
|
|
203
|
+
log?: GatewayLogger,
|
|
204
|
+
detail?: string,
|
|
205
|
+
): Promise<void> {
|
|
191
206
|
try {
|
|
192
|
-
await this.fail(delivery);
|
|
207
|
+
await this.fail(delivery, detail);
|
|
193
208
|
} catch (err) {
|
|
194
209
|
log?.warn?.(
|
|
195
210
|
`failed to report Claude input ${delivery.commandUuid} as failed: ${String(err)}`,
|
|
@@ -197,11 +212,11 @@ export class ClaudeInputRegistry {
|
|
|
197
212
|
}
|
|
198
213
|
}
|
|
199
214
|
|
|
200
|
-
async failAllBestEffort(log?: GatewayLogger): Promise<void> {
|
|
215
|
+
async failAllBestEffort(log?: GatewayLogger, detail?: string): Promise<void> {
|
|
201
216
|
await Promise.all(
|
|
202
217
|
[...this.byKey.values()]
|
|
203
218
|
.filter((delivery) => !delivery.terminal)
|
|
204
|
-
.map((delivery) => this.failBestEffort(delivery, log)),
|
|
219
|
+
.map((delivery) => this.failBestEffort(delivery, log, detail)),
|
|
205
220
|
);
|
|
206
221
|
}
|
|
207
222
|
}
|
package/src/process-pump.ts
CHANGED
|
@@ -470,8 +470,11 @@ export class ClaudeProcessPump {
|
|
|
470
470
|
if (!delivery.terminal && settledAsLimit(delivery.evidence))
|
|
471
471
|
delivery.suppressFailReport = true;
|
|
472
472
|
}
|
|
473
|
-
|
|
474
|
-
for
|
|
473
|
+
// Failing removes drained deliveries from the registry. Their sinks must
|
|
474
|
+
// still receive EOF, or a startup failure waits for the dispatch timeout.
|
|
475
|
+
const deliveries = [...inputs.values()];
|
|
476
|
+
await inputs.failAllBestEffort(log, message);
|
|
477
|
+
for (const delivery of deliveries) {
|
|
475
478
|
delivery.sink.push({ kind: 'ended', reason: 'eof', message });
|
|
476
479
|
delivery.sink.close();
|
|
477
480
|
}
|