diff --git a/packages/ai-runtime/src/context-compression.test.ts b/packages/ai-runtime/src/context-compression.test.ts new file mode 100644 index 00000000..fedc0c33 --- /dev/null +++ b/packages/ai-runtime/src/context-compression.test.ts @@ -0,0 +1,12 @@ +import assert from 'node:assert/strict' +import { describe, it } from 'node:test' + +import { resolveRuntimeContextWindow } from './context-compression' + +describe('resolveRuntimeContextWindow', () => { + it('uses only exact provider matches and a conservative fallback for custom endpoints', () => { + assert.equal(resolveRuntimeContextWindow('deepseek', 'deepseek-v4-flash'), 1_000_000) + assert.equal(resolveRuntimeContextWindow('openai-compatible', 'gpt-5'), 8_192) + assert.equal(resolveRuntimeContextWindow('openai-compatible', 'custom-model'), 8_192) + }) +}) diff --git a/packages/ai-runtime/src/context-compression.ts b/packages/ai-runtime/src/context-compression.ts index 5d830176..ae228fef 100644 --- a/packages/ai-runtime/src/context-compression.ts +++ b/packages/ai-runtime/src/context-compression.ts @@ -1,9 +1,12 @@ -import { BUILTIN_MODELS, getBuiltinModelById } from '@openchatlab/core' +import { getBuiltinModelById } from '@openchatlab/core' import { generateText } from 'ai' import type { RunAgentInput, RuntimeContextSummary, RuntimeMessage } from './types' -const DEFAULT_CONTEXT_WINDOW = 32_768 +// OpenAI-compatible endpoints do not expose standard context-window metadata. +// Underestimating an unknown model compresses earlier; overestimating it makes +// the provider reject an otherwise recoverable conversation. +const DEFAULT_CONTEXT_WINDOW = 8_192 const COMPRESSION_THRESHOLD_PERCENT = 75 const BUFFER_SIZE_PERCENT = 20 const MAX_SUMMARY_TOKENS = 4_096 @@ -18,9 +21,7 @@ Merge the previous summary when present. Do not copy long passages verbatim. {history}` export function resolveRuntimeContextWindow(providerId: string, modelId: string): number { - const exact = getBuiltinModelById(providerId, modelId) - const knownById = exact ?? BUILTIN_MODELS.find((model) => model.id === modelId) - return knownById?.contextWindow ?? DEFAULT_CONTEXT_WINDOW + return getBuiltinModelById(providerId, modelId)?.contextWindow ?? DEFAULT_CONTEXT_WINDOW } export async function prepareContextMessages(