Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/max-output-size-completion-budget.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@moonshot-ai/agent-core": patch
"@moonshot-ai/kimi-code": patch
---

Use configured model output limits as completion token caps.
1 change: 1 addition & 0 deletions packages/agent-core/src/agent/compaction/full.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ export class FullCompaction {
const provider = applyCompletionBudget({
provider: this.agent.config.provider,
budget: resolveCompletionBudget({
maxOutputSize: this.agent.config.maxOutputSize,
reservedContextSize: this.agent.kimiConfig?.loopControl?.reservedContextSize,
}),
capability: this.agent.config.modelCapabilities,
Expand Down
4 changes: 4 additions & 0 deletions packages/agent-core/src/agent/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ export class ConfigState {
return this.tryResolvedProviderConfig()?.modelCapabilities ?? UNKNOWN_CAPABILITY;
}

get maxOutputSize(): number | undefined {
return this.tryResolvedProviderConfig()?.maxOutputSize;
}

private get resolvedProviderConfig(): ResolvedRuntimeProvider | undefined {
if (this._modelAlias === undefined) return undefined;
return this.agent.modelProvider?.resolveProviderConfig(this._modelAlias);
Expand Down
1 change: 1 addition & 0 deletions packages/agent-core/src/agent/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ export class Agent {
const provider = this.config.provider.withThinking(this.config.thinkingLevel);
const loopControl = this.kimiConfig?.loopControl;
const completionBudgetConfig = resolveCompletionBudget({
maxOutputSize: this.config.maxOutputSize,
reservedContextSize: loopControl?.reservedContextSize,
});
return new KosongLLM({
Expand Down
2 changes: 2 additions & 0 deletions packages/agent-core/src/session/provider-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface ResolvedRuntimeProvider {
readonly providerName: string;
readonly provider: KosongProviderConfig;
readonly modelCapabilities: ModelCapability;
readonly maxOutputSize?: number | undefined;
}

interface ProviderManagerOptions {
Expand Down Expand Up @@ -115,6 +116,7 @@ export class ProviderManager implements ModelProvider {
providerName,
provider,
modelCapabilities: resolveModelCapabilities(alias, provider),
maxOutputSize: alias.maxOutputSize,
};
}

Expand Down
4 changes: 4 additions & 0 deletions packages/agent-core/src/utils/completion-budget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const DEFAULT_UNKNOWN_CONTEXT_FALLBACK = 32000;
* non-positive env values disable clamping.
*/
export function resolveCompletionBudget(args: {
readonly maxOutputSize?: number | undefined;
readonly reservedContextSize?: number;
readonly env?: NodeJS.ProcessEnv;
}): CompletionBudgetConfig | undefined {
Expand All @@ -28,6 +29,9 @@ export function resolveCompletionBudget(args: {
if (fromLegacy !== 'absent') {
return fromLegacy === 'disabled' ? undefined : { hardCap: fromLegacy };
}
if (args.maxOutputSize !== undefined) {
return { hardCap: args.maxOutputSize };
}
if (args.reservedContextSize !== undefined && args.reservedContextSize > 0) {
return { fallback: args.reservedContextSize };
}
Expand Down
2 changes: 2 additions & 0 deletions packages/agent-core/test/harness/runtime-provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ describe('resolveRuntimeProvider model metadata', () => {
provider: 'openai',
model: 'gpt-runtime',
maxContextSize: 200000,
maxOutputSize: 24000,
capabilities: ['tool_use'],
},
},
Expand All @@ -106,6 +107,7 @@ describe('resolveRuntimeProvider model metadata', () => {
tool_use: true,
max_context_tokens: 200000,
});
expect(resolved.maxOutputSize).toBe(24000);
});

it('uses config Kimi capabilities without requiring an api key during OAuth setup', () => {
Expand Down
18 changes: 18 additions & 0 deletions packages/agent-core/test/utils/completion-budget.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,24 @@ describe('resolveCompletionBudget', () => {
expect(budget?.hardCap).toBe(2048);
});

it('uses maxOutputSize as the hard cap when env vars are unset', () => {
const budget = resolveCompletionBudget({
maxOutputSize: 2048,
reservedContextSize: 1000,
env: {},
});
expect(budget?.hardCap).toBe(2048);
expect(budget?.fallback).toBeUndefined();
});

it('lets env vars override maxOutputSize', () => {
const budget = resolveCompletionBudget({
maxOutputSize: 2048,
env: { KIMI_MODEL_MAX_COMPLETION_TOKENS: '4096' },
});
expect(budget?.hardCap).toBe(4096);
});

it('uses reservedContextSize as the unknown-context fallback when no env var is set', () => {
const budget = resolveCompletionBudget({
reservedContextSize: 12345,
Expand Down