Skip to content
Merged
4 changes: 2 additions & 2 deletions packages/api/src/agents/__tests__/run-summarization.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ describe('summarizationConfig field passthrough', () => {
const agents = await callAndCapture({
summarizationConfig: {
enabled: true,
trigger: { type: 'token_count', value: 8000 },
trigger: { type: 'token_ratio', value: 0.8 },
provider: 'anthropic',
model: 'claude-3-haiku',
parameters: { temperature: 0.2 },
Expand All @@ -233,7 +233,7 @@ describe('summarizationConfig field passthrough', () => {
// `enabled` is not forwarded to the agent-level config β€” it is resolved
// into the separate `summarizationEnabled` boolean on the agent input.
expect(agents[0].summarizationEnabled).toBe(true);
expect(config.trigger).toEqual({ type: 'token_count', value: 8000 });
expect(config.trigger).toEqual({ type: 'token_ratio', value: 0.8 });
expect(config.provider).toBe('anthropic');
expect(config.model).toBe('claude-3-haiku');
expect(config.parameters).toEqual({ temperature: 0.2 });
Expand Down
45 changes: 45 additions & 0 deletions packages/data-provider/specs/config-schemas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
interfaceSchema,
fileStorageSchema,
fileStrategiesSchema,
summarizationTriggerSchema,
summarizationConfigSchema,
} from '../src/config';
import { tModelSpecPresetSchema, EModelEndpoint } from '../src/schemas';
import { FileSources } from '../src/types/files';
Expand Down Expand Up @@ -502,3 +504,46 @@ describe('interfaceSchema', () => {
expect(result.modelSelect).toBe(false);
});
});

describe('summarizationTriggerSchema', () => {
it.each(['token_ratio', 'remaining_tokens', 'messages_to_refine'] as const)(
'accepts documented trigger type "%s"',
(type) => {
const result = summarizationTriggerSchema.safeParse({ type, value: 0.8 });
expect(result.success).toBe(true);
},
);

it('rejects the legacy/typoed "token_count" trigger type', () => {
const result = summarizationTriggerSchema.safeParse({
type: 'token_count',
value: 8000,
});
expect(result.success).toBe(false);
});

it('rejects unknown trigger types', () => {
const result = summarizationTriggerSchema.safeParse({
type: 'never_heard_of_it',
value: 1,
});
expect(result.success).toBe(false);
});

it('rejects zero or negative values', () => {
expect(summarizationTriggerSchema.safeParse({ type: 'token_ratio', value: 0 }).success).toBe(
false,
);
expect(summarizationTriggerSchema.safeParse({ type: 'token_ratio', value: -0.5 }).success).toBe(
false,
);
});

it('parses inside the full summarization config', () => {
const result = summarizationConfigSchema.safeParse({
enabled: true,
trigger: { type: 'token_ratio', value: 0.8 },
});
expect(result.success).toBe(true);
});
});
2 changes: 1 addition & 1 deletion packages/data-provider/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,7 @@ export const memorySchema = z.object({
export type TMemoryConfig = DeepPartial<z.infer<typeof memorySchema>>;

export const summarizationTriggerSchema = z.object({
type: z.enum(['token_count']),
type: z.enum(['token_ratio', 'remaining_tokens', 'messages_to_refine']),
value: z.number().positive(),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Constrain token_ratio trigger values to 0–1

summarizationTriggerSchema now accepts type: "token_ratio", but value is only validated as positive(), so values greater than 1 (for example 80) pass schema validation even though token usage ratio cannot exceed 1.0. In that configuration, summarization will never trigger, recreating a silent no-op path for misconfigured but schema-valid YAML; this is especially risky because the docs describe token_ratio as a fraction in the 0.0–1.0 range.

Useful? React with πŸ‘Β / πŸ‘Ž.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 599c0fe β€” switched to a discriminated union so token_ratio is bounded to (0, 1] while remaining_tokens and messages_to_refine keep unconstrained positive values (they're counts, not fractions). Added tests for value: 80 and value: 1.01 being rejected and value: 1 being accepted at the upper bound.

});

Expand Down
Loading