@parall/claude-agent 1.58.0 → 1.58.2
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 +4 -0
- package/dist/dispatch.d.ts.map +1 -1
- package/dist/dispatch.js +8 -2
- package/dist/index.js +6 -1
- package/dist/spawn-env.d.ts +1 -0
- package/dist/spawn-env.d.ts.map +1 -1
- package/dist/spawn-env.js +21 -4
- package/package.json +4 -4
- package/src/dispatch.ts +10 -2
- package/src/index.ts +9 -0
- package/src/spawn-env.ts +24 -4
package/dist/dispatch.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ type ClaudeCodeAdapterOptions = Pick<ClaudeAgentConfig, 'additionalDirs' | 'allo
|
|
|
10
10
|
orgId: string;
|
|
11
11
|
/** Catalog context size for the selected model. */
|
|
12
12
|
contextWindow?: number;
|
|
13
|
+
/** Catalog max output tokens for the selected model (input-budget subtrahend). */
|
|
14
|
+
maxTokens?: number;
|
|
13
15
|
contextFilePathForSession?: (sessionKey: string) => string;
|
|
14
16
|
/** @deprecated Use contextFilePathForSession. */
|
|
15
17
|
stepIdFilePathForSession?: (sessionKey: string) => string;
|
|
@@ -41,6 +43,7 @@ export declare class ClaudeCodeAdapter implements DispatchAdapter {
|
|
|
41
43
|
private _model;
|
|
42
44
|
private _effortLevel;
|
|
43
45
|
private _contextWindow;
|
|
46
|
+
private _maxTokens;
|
|
44
47
|
constructor(opts: ClaudeCodeAdapterOptions);
|
|
45
48
|
get currentModel(): string | undefined;
|
|
46
49
|
get currentEffort(): string | undefined;
|
|
@@ -48,6 +51,7 @@ export declare class ClaudeCodeAdapter implements DispatchAdapter {
|
|
|
48
51
|
model?: string | null;
|
|
49
52
|
effort?: string | null;
|
|
50
53
|
contextWindow?: number | null;
|
|
54
|
+
maxTokens?: number | null;
|
|
51
55
|
}): void;
|
|
52
56
|
requestProcessRestart(): void;
|
|
53
57
|
enqueueDuringDispatch(sessionKey: string, body: string, inputLifecycle?: DispatchInputLifecycle): boolean;
|
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,eAAe,EACf,sBAAsB,EACtB,YAAY,EACZ,QAAQ,EAER,YAAY,EACb,MAAM,oBAAoB,CAAC;AAK5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAOrD,OAAO,KAAK,EAAuB,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,yBAAyB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3D,iDAAiD;IACjD,wBAAwB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1D;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAqCF,qBAAa,iBAAkB,YAAW,eAAe;
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"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"}
|
package/dist/dispatch.js
CHANGED
|
@@ -36,10 +36,12 @@ export class ClaudeCodeAdapter {
|
|
|
36
36
|
_model;
|
|
37
37
|
_effortLevel;
|
|
38
38
|
_contextWindow;
|
|
39
|
+
_maxTokens;
|
|
39
40
|
constructor(opts) {
|
|
40
41
|
this.opts = opts;
|
|
41
42
|
this._model = opts.model;
|
|
42
43
|
this._contextWindow = opts.contextWindow;
|
|
44
|
+
this._maxTokens = opts.maxTokens;
|
|
43
45
|
}
|
|
44
46
|
get currentModel() {
|
|
45
47
|
return this._model;
|
|
@@ -51,13 +53,16 @@ export class ClaudeCodeAdapter {
|
|
|
51
53
|
const modelChanged = config.model !== undefined && config.model !== this._model;
|
|
52
54
|
const effortChanged = config.effort !== undefined && config.effort !== this._effortLevel;
|
|
53
55
|
const contextWindowChanged = config.contextWindow !== undefined && config.contextWindow !== this._contextWindow;
|
|
56
|
+
const maxTokensChanged = config.maxTokens !== undefined && config.maxTokens !== this._maxTokens;
|
|
54
57
|
if (modelChanged)
|
|
55
58
|
this._model = config.model ?? undefined;
|
|
56
59
|
if (effortChanged)
|
|
57
60
|
this._effortLevel = config.effort ?? undefined;
|
|
58
61
|
if (contextWindowChanged)
|
|
59
62
|
this._contextWindow = config.contextWindow ?? undefined;
|
|
60
|
-
if (
|
|
63
|
+
if (maxTokensChanged)
|
|
64
|
+
this._maxTokens = config.maxTokens ?? undefined;
|
|
65
|
+
if (modelChanged || effortChanged || contextWindowChanged || maxTokensChanged) {
|
|
61
66
|
this.requestProcessRestart();
|
|
62
67
|
}
|
|
63
68
|
}
|
|
@@ -513,11 +518,12 @@ export class ClaudeCodeAdapter {
|
|
|
513
518
|
const env = buildSpawnEnv(process.env, this.opts.claudeHome, this.buildPlaceholderContext(sessionKey), {
|
|
514
519
|
allowApiKey: this.opts.allowApiKey,
|
|
515
520
|
contextWindow: this._contextWindow,
|
|
521
|
+
maxTokens: this._maxTokens,
|
|
516
522
|
effortLevel: this._effortLevel,
|
|
517
523
|
wikiMountRoot: this.opts.workspaceDir,
|
|
518
524
|
capabilityBinDir: this.opts.capabilityBinDir,
|
|
519
525
|
});
|
|
520
|
-
log?.info(`spawn long-lived ${this.opts.claudeBin} (session ${sessionKey}, model=${this._model || 'default'}, context=${this._contextWindow || 'cli-default'}, effort=${this._effortLevel || 'default'}, mode=${this.opts.permissionMode})`);
|
|
526
|
+
log?.info(`spawn long-lived ${this.opts.claudeBin} (session ${sessionKey}, model=${this._model || 'default'}, context=${this._contextWindow || 'cli-default'}, maxOut=${this._maxTokens || 'cli-default'}, effort=${this._effortLevel || 'default'}, mode=${this.opts.permissionMode})`);
|
|
521
527
|
const proc = spawn(IS_WIN32 ? quoteWin32Arg(this.opts.claudeBin) : this.opts.claudeBin, IS_WIN32 ? args.map(quoteWin32Arg) : args, {
|
|
522
528
|
cwd: this.opts.workspaceDir,
|
|
523
529
|
env,
|
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, materializeChannelCapabilities, ParallAgentGateway, parseDispatchDeadlineMs, parseForkDeadlineMs, parseProviderConfig, parseShutdownDeadlineMs, resolveRuntimeContextWindow, resolveRuntimeModel, } from '@parall/agent-core';
|
|
3
|
+
import { capabilityBinDir, childLogger, clearAllProviderCreds, configureHttpKeepAlive, createLogger, createOtelLogger, createPlatformConfigManager, deriveModelIsPin, identityFromMe, initAgentTelemetry, llmSource, materializeChannelCapabilities, ParallAgentGateway, parseDispatchDeadlineMs, parseForkDeadlineMs, parseProviderConfig, parseShutdownDeadlineMs, resolveRuntimeContextWindow, resolveRuntimeMaxTokens, resolveRuntimeModel, } 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';
|
|
@@ -113,6 +113,7 @@ async function main() {
|
|
|
113
113
|
const platformModelOverride = deriveModelIsPin(platformDefaults, me.agent_profile);
|
|
114
114
|
const resolvedModel = resolveRuntimeModel(platformModelOverride, platformDefaults.model, config.model);
|
|
115
115
|
const resolvedContextWindow = resolveRuntimeContextWindow(resolvedModel, platformDefaults, activeLLMSource);
|
|
116
|
+
const resolvedMaxTokens = resolveRuntimeMaxTokens(resolvedModel, platformDefaults, activeLLMSource);
|
|
116
117
|
const resolvedEffort = platformDefaults.thinkingEffort ??
|
|
117
118
|
(process.env.CLAUDE_CODE_EFFORT_LEVEL?.trim() || undefined);
|
|
118
119
|
if (platformDefaults.model)
|
|
@@ -121,12 +122,15 @@ async function main() {
|
|
|
121
122
|
agentLog.info(`platform config: thinking_effort=${platformDefaults.thinkingEffort}`);
|
|
122
123
|
if (resolvedContextWindow)
|
|
123
124
|
agentLog.info(`platform config: context_window=${resolvedContextWindow}`);
|
|
125
|
+
if (resolvedMaxTokens)
|
|
126
|
+
agentLog.info(`platform config: max_tokens=${resolvedMaxTokens}`);
|
|
124
127
|
const adapter = new ClaudeCodeAdapter({
|
|
125
128
|
claudeBin: config.claudeBin,
|
|
126
129
|
claudeHome: config.claudeHome,
|
|
127
130
|
workspaceDir: config.workspaceDir,
|
|
128
131
|
model: resolvedModel,
|
|
129
132
|
contextWindow: resolvedContextWindow,
|
|
133
|
+
maxTokens: resolvedMaxTokens,
|
|
130
134
|
permissionMode: config.permissionMode,
|
|
131
135
|
allowedTools: config.allowedTools,
|
|
132
136
|
disallowedTools: config.disallowedTools,
|
|
@@ -179,6 +183,7 @@ async function main() {
|
|
|
179
183
|
adapter.updateConfig({
|
|
180
184
|
model,
|
|
181
185
|
contextWindow: resolveRuntimeContextWindow(model, updated, activeLLMSource) ?? null,
|
|
186
|
+
maxTokens: resolveRuntimeMaxTokens(model, updated, activeLLMSource) ?? null,
|
|
182
187
|
effort: updated.thinkingEffort ?? localEffort,
|
|
183
188
|
});
|
|
184
189
|
// Channel capabilities heat-update with the config: re-materialize the
|
package/dist/spawn-env.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { DispatchOpts } from '@parall/agent-core';
|
|
|
2
2
|
export declare function buildSpawnEnv(parentEnv: NodeJS.ProcessEnv, claudeHome: string, context: DispatchOpts['context'], opts: {
|
|
3
3
|
allowApiKey: boolean;
|
|
4
4
|
contextWindow?: number;
|
|
5
|
+
maxTokens?: number;
|
|
5
6
|
effortLevel?: string;
|
|
6
7
|
wikiMountRoot?: string;
|
|
7
8
|
capabilityBinDir?: string;
|
package/dist/spawn-env.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn-env.d.ts","sourceRoot":"","sources":["../src/spawn-env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,CAAC,UAAU,EAC5B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,EAChC,IAAI,EAAE;IACJ,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,GACA,MAAM,CAAC,UAAU,
|
|
1
|
+
{"version":3,"file":"spawn-env.d.ts","sourceRoot":"","sources":["../src/spawn-env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,CAAC,UAAU,EAC5B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,EAChC,IAAI,EAAE;IACJ,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,GACA,MAAM,CAAC,UAAU,CAiFnB"}
|
package/dist/spawn-env.js
CHANGED
|
@@ -35,10 +35,27 @@ export function buildSpawnEnv(parentEnv, claudeHome, context, opts) {
|
|
|
35
35
|
if (typeof opts.contextWindow === 'number' &&
|
|
36
36
|
Number.isSafeInteger(opts.contextWindow) &&
|
|
37
37
|
opts.contextWindow > 0) {
|
|
38
|
-
// Claude Code otherwise assumes 200k for an unrecognized model ID.
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
|
|
38
|
+
// Claude Code otherwise assumes 200k for an unrecognized model ID.
|
|
39
|
+
//
|
|
40
|
+
// Declared as the model's INPUT budget (context_window - max_tokens; both
|
|
41
|
+
// raw catalog facts), not the full window. The upstream validates
|
|
42
|
+
// input + max_tokens <= context_window, while the CLI requests up to its
|
|
43
|
+
// own output default (32k) yet reserves at most 20k below this declared
|
|
44
|
+
// boundary before auto-compacting (2.1.251) — so a session declared the
|
|
45
|
+
// full window can grow into a band the provider already rejects but the
|
|
46
|
+
// CLI still considers legal: it retries forever, auto-compact never
|
|
47
|
+
// fires, and once past the boundary the compaction call itself is
|
|
48
|
+
// over-limit (the ParallSRE 08-31 lockup). Subtracting the catalog
|
|
49
|
+
// max_tokens keeps the compaction trigger strictly inside what the
|
|
50
|
+
// provider accepts.
|
|
51
|
+
let inputBudget = opts.contextWindow;
|
|
52
|
+
if (typeof opts.maxTokens === 'number' &&
|
|
53
|
+
Number.isSafeInteger(opts.maxTokens) &&
|
|
54
|
+
opts.maxTokens > 0 &&
|
|
55
|
+
opts.maxTokens < opts.contextWindow) {
|
|
56
|
+
inputBudget = opts.contextWindow - opts.maxTokens;
|
|
57
|
+
}
|
|
58
|
+
result.CLAUDE_CODE_MAX_CONTEXT_TOKENS = String(inputBudget);
|
|
42
59
|
}
|
|
43
60
|
// Channel-capability shims resolve ahead of any globally-installed CLI of
|
|
44
61
|
// the same name (the shim owns auth; the real binary is found further down
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/claude-agent",
|
|
3
|
-
"version": "1.58.
|
|
3
|
+
"version": "1.58.2",
|
|
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.58.
|
|
29
|
-
"@parall/cli": "1.58.
|
|
30
|
-
"@parall/sdk": "1.58.
|
|
28
|
+
"@parall/agent-core": "1.58.2",
|
|
29
|
+
"@parall/cli": "1.58.2",
|
|
30
|
+
"@parall/sdk": "1.58.2"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^22.0.0",
|
package/src/dispatch.ts
CHANGED
|
@@ -47,6 +47,8 @@ type ClaudeCodeAdapterOptions = Pick<
|
|
|
47
47
|
orgId: string;
|
|
48
48
|
/** Catalog context size for the selected model. */
|
|
49
49
|
contextWindow?: number;
|
|
50
|
+
/** Catalog max output tokens for the selected model (input-budget subtrahend). */
|
|
51
|
+
maxTokens?: number;
|
|
50
52
|
contextFilePathForSession?: (sessionKey: string) => string;
|
|
51
53
|
/** @deprecated Use contextFilePathForSession. */
|
|
52
54
|
stepIdFilePathForSession?: (sessionKey: string) => string;
|
|
@@ -113,10 +115,12 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
|
|
|
113
115
|
private _model: string | undefined;
|
|
114
116
|
private _effortLevel: string | undefined;
|
|
115
117
|
private _contextWindow: number | undefined;
|
|
118
|
+
private _maxTokens: number | undefined;
|
|
116
119
|
|
|
117
120
|
constructor(private readonly opts: ClaudeCodeAdapterOptions) {
|
|
118
121
|
this._model = opts.model;
|
|
119
122
|
this._contextWindow = opts.contextWindow;
|
|
123
|
+
this._maxTokens = opts.maxTokens;
|
|
120
124
|
}
|
|
121
125
|
|
|
122
126
|
get currentModel(): string | undefined {
|
|
@@ -129,15 +133,18 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
|
|
|
129
133
|
model?: string | null;
|
|
130
134
|
effort?: string | null;
|
|
131
135
|
contextWindow?: number | null;
|
|
136
|
+
maxTokens?: number | null;
|
|
132
137
|
}): void {
|
|
133
138
|
const modelChanged = config.model !== undefined && config.model !== this._model;
|
|
134
139
|
const effortChanged = config.effort !== undefined && config.effort !== this._effortLevel;
|
|
135
140
|
const contextWindowChanged =
|
|
136
141
|
config.contextWindow !== undefined && config.contextWindow !== this._contextWindow;
|
|
142
|
+
const maxTokensChanged = config.maxTokens !== undefined && config.maxTokens !== this._maxTokens;
|
|
137
143
|
if (modelChanged) this._model = config.model ?? undefined;
|
|
138
144
|
if (effortChanged) this._effortLevel = config.effort ?? undefined;
|
|
139
145
|
if (contextWindowChanged) this._contextWindow = config.contextWindow ?? undefined;
|
|
140
|
-
if (
|
|
146
|
+
if (maxTokensChanged) this._maxTokens = config.maxTokens ?? undefined;
|
|
147
|
+
if (modelChanged || effortChanged || contextWindowChanged || maxTokensChanged) {
|
|
141
148
|
this.requestProcessRestart();
|
|
142
149
|
}
|
|
143
150
|
}
|
|
@@ -664,6 +671,7 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
|
|
|
664
671
|
{
|
|
665
672
|
allowApiKey: this.opts.allowApiKey,
|
|
666
673
|
contextWindow: this._contextWindow,
|
|
674
|
+
maxTokens: this._maxTokens,
|
|
667
675
|
effortLevel: this._effortLevel,
|
|
668
676
|
wikiMountRoot: this.opts.workspaceDir,
|
|
669
677
|
capabilityBinDir: this.opts.capabilityBinDir,
|
|
@@ -671,7 +679,7 @@ export class ClaudeCodeAdapter implements DispatchAdapter {
|
|
|
671
679
|
);
|
|
672
680
|
|
|
673
681
|
log?.info(
|
|
674
|
-
`spawn long-lived ${this.opts.claudeBin} (session ${sessionKey}, model=${this._model || 'default'}, context=${this._contextWindow || 'cli-default'}, effort=${this._effortLevel || 'default'}, mode=${this.opts.permissionMode})`,
|
|
682
|
+
`spawn long-lived ${this.opts.claudeBin} (session ${sessionKey}, model=${this._model || 'default'}, context=${this._contextWindow || 'cli-default'}, maxOut=${this._maxTokens || 'cli-default'}, effort=${this._effortLevel || 'default'}, mode=${this.opts.permissionMode})`,
|
|
675
683
|
);
|
|
676
684
|
|
|
677
685
|
const proc = spawn(
|
package/src/index.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
parseProviderConfig,
|
|
21
21
|
parseShutdownDeadlineMs,
|
|
22
22
|
resolveRuntimeContextWindow,
|
|
23
|
+
resolveRuntimeMaxTokens,
|
|
23
24
|
resolveRuntimeModel,
|
|
24
25
|
} from '@parall/agent-core';
|
|
25
26
|
import { ApiError, ParallClient, ParallWs } from '@parall/sdk';
|
|
@@ -159,6 +160,11 @@ async function main() {
|
|
|
159
160
|
platformDefaults,
|
|
160
161
|
activeLLMSource,
|
|
161
162
|
);
|
|
163
|
+
const resolvedMaxTokens = resolveRuntimeMaxTokens(
|
|
164
|
+
resolvedModel,
|
|
165
|
+
platformDefaults,
|
|
166
|
+
activeLLMSource,
|
|
167
|
+
);
|
|
162
168
|
const resolvedEffort =
|
|
163
169
|
platformDefaults.thinkingEffort ??
|
|
164
170
|
(process.env.CLAUDE_CODE_EFFORT_LEVEL?.trim() || undefined);
|
|
@@ -170,6 +176,7 @@ async function main() {
|
|
|
170
176
|
agentLog.info(`platform config: thinking_effort=${platformDefaults.thinkingEffort}`);
|
|
171
177
|
if (resolvedContextWindow)
|
|
172
178
|
agentLog.info(`platform config: context_window=${resolvedContextWindow}`);
|
|
179
|
+
if (resolvedMaxTokens) agentLog.info(`platform config: max_tokens=${resolvedMaxTokens}`);
|
|
173
180
|
|
|
174
181
|
const adapter = new ClaudeCodeAdapter({
|
|
175
182
|
claudeBin: config.claudeBin,
|
|
@@ -177,6 +184,7 @@ async function main() {
|
|
|
177
184
|
workspaceDir: config.workspaceDir,
|
|
178
185
|
model: resolvedModel,
|
|
179
186
|
contextWindow: resolvedContextWindow,
|
|
187
|
+
maxTokens: resolvedMaxTokens,
|
|
180
188
|
permissionMode: config.permissionMode,
|
|
181
189
|
allowedTools: config.allowedTools,
|
|
182
190
|
disallowedTools: config.disallowedTools,
|
|
@@ -233,6 +241,7 @@ async function main() {
|
|
|
233
241
|
adapter.updateConfig({
|
|
234
242
|
model,
|
|
235
243
|
contextWindow: resolveRuntimeContextWindow(model, updated, activeLLMSource) ?? null,
|
|
244
|
+
maxTokens: resolveRuntimeMaxTokens(model, updated, activeLLMSource) ?? null,
|
|
236
245
|
effort: updated.thinkingEffort ?? localEffort,
|
|
237
246
|
});
|
|
238
247
|
// Channel capabilities heat-update with the config: re-materialize the
|
package/src/spawn-env.ts
CHANGED
|
@@ -8,6 +8,7 @@ export function buildSpawnEnv(
|
|
|
8
8
|
opts: {
|
|
9
9
|
allowApiKey: boolean;
|
|
10
10
|
contextWindow?: number;
|
|
11
|
+
maxTokens?: number;
|
|
11
12
|
effortLevel?: string;
|
|
12
13
|
wikiMountRoot?: string;
|
|
13
14
|
capabilityBinDir?: string;
|
|
@@ -50,10 +51,29 @@ export function buildSpawnEnv(
|
|
|
50
51
|
Number.isSafeInteger(opts.contextWindow) &&
|
|
51
52
|
opts.contextWindow > 0
|
|
52
53
|
) {
|
|
53
|
-
// Claude Code otherwise assumes 200k for an unrecognized model ID.
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
|
|
54
|
+
// Claude Code otherwise assumes 200k for an unrecognized model ID.
|
|
55
|
+
//
|
|
56
|
+
// Declared as the model's INPUT budget (context_window - max_tokens; both
|
|
57
|
+
// raw catalog facts), not the full window. The upstream validates
|
|
58
|
+
// input + max_tokens <= context_window, while the CLI requests up to its
|
|
59
|
+
// own output default (32k) yet reserves at most 20k below this declared
|
|
60
|
+
// boundary before auto-compacting (2.1.251) — so a session declared the
|
|
61
|
+
// full window can grow into a band the provider already rejects but the
|
|
62
|
+
// CLI still considers legal: it retries forever, auto-compact never
|
|
63
|
+
// fires, and once past the boundary the compaction call itself is
|
|
64
|
+
// over-limit (the ParallSRE 08-31 lockup). Subtracting the catalog
|
|
65
|
+
// max_tokens keeps the compaction trigger strictly inside what the
|
|
66
|
+
// provider accepts.
|
|
67
|
+
let inputBudget = opts.contextWindow;
|
|
68
|
+
if (
|
|
69
|
+
typeof opts.maxTokens === 'number' &&
|
|
70
|
+
Number.isSafeInteger(opts.maxTokens) &&
|
|
71
|
+
opts.maxTokens > 0 &&
|
|
72
|
+
opts.maxTokens < opts.contextWindow
|
|
73
|
+
) {
|
|
74
|
+
inputBudget = opts.contextWindow - opts.maxTokens;
|
|
75
|
+
}
|
|
76
|
+
result.CLAUDE_CODE_MAX_CONTEXT_TOKENS = String(inputBudget);
|
|
57
77
|
}
|
|
58
78
|
// Channel-capability shims resolve ahead of any globally-installed CLI of
|
|
59
79
|
// the same name (the shim owns auth; the real binary is found further down
|