From e72dc619cf90f24b093b88caafc6e098b93d9851 Mon Sep 17 00:00:00 2001 From: Jaakko Husso Date: Mon, 20 Oct 2025 12:45:29 +0300 Subject: [PATCH] feat(core): Limit chat history context window length with a map of limits (no-changelog) (#20955) --- .../src/modules/chat-hub/chat-hub.service.ts | 21 ++- .../src/modules/chat-hub/context-limits.ts | 152 ++++++++++++++++++ 2 files changed, 166 insertions(+), 7 deletions(-) create mode 100644 packages/cli/src/modules/chat-hub/context-limits.ts diff --git a/packages/cli/src/modules/chat-hub/chat-hub.service.ts b/packages/cli/src/modules/chat-hub/chat-hub.service.ts index 77ce9f9aa45..aa467d76add 100644 --- a/packages/cli/src/modules/chat-hub/chat-hub.service.ts +++ b/packages/cli/src/modules/chat-hub/chat-hub.service.ts @@ -26,6 +26,7 @@ import type { Response } from 'express'; import { AGENT_LANGCHAIN_NODE_TYPE, CHAT_TRIGGER_NODE_TYPE, + NodeConnectionTypes, OperationalError, type IConnections, type INode, @@ -48,6 +49,7 @@ import type { } from './chat-hub.types'; import { ChatHubMessageRepository } from './chat-message.repository'; import { ChatHubSessionRepository } from './chat-session.repository'; +import { getMaxContextWindowTokens } from './context-limits'; import { ActiveExecutions } from '@/active-executions'; import { CredentialsService } from '@/credentials/credentials.service'; @@ -617,6 +619,7 @@ export class ChatHubService { text: "={{ $('When chat message received').item.json.chatInput }}", options: { enableStreaming: true, + maxTokensFromMemory: getMaxContextWindowTokens(model.provider, model.model), }, }, type: AGENT_LANGCHAIN_NODE_TYPE, @@ -680,21 +683,25 @@ export class ChatHubService { const connections: IConnections = { [NODE_NAMES.CHAT_TRIGGER]: { - main: [[{ node: NODE_NAMES.RESTORE_CHAT_MEMORY, type: 'main', index: 0 }]], + main: [ + [{ node: NODE_NAMES.RESTORE_CHAT_MEMORY, type: NodeConnectionTypes.Main, index: 0 }], + ], }, [NODE_NAMES.RESTORE_CHAT_MEMORY]: { - main: [[{ node: NODE_NAMES.AI_AGENT, type: 'main', index: 0 }]], + main: [[{ node: NODE_NAMES.AI_AGENT, type: NodeConnectionTypes.Main, index: 0 }]], }, [NODE_NAMES.CHAT_MODEL]: { // eslint-disable-next-line @typescript-eslint/naming-convention - ai_languageModel: [[{ node: NODE_NAMES.AI_AGENT, type: 'ai_languageModel', index: 0 }]], + ai_languageModel: [ + [{ node: NODE_NAMES.AI_AGENT, type: NodeConnectionTypes.AiLanguageModel, index: 0 }], + ], }, [NODE_NAMES.MEMORY]: { ai_memory: [ [ - { node: NODE_NAMES.AI_AGENT, type: 'ai_memory', index: 0 }, - { node: NODE_NAMES.RESTORE_CHAT_MEMORY, type: 'ai_memory', index: 0 }, - { node: NODE_NAMES.CLEAR_CHAT_MEMORY, type: 'ai_memory', index: 0 }, + { node: NODE_NAMES.AI_AGENT, type: NodeConnectionTypes.AiMemory, index: 0 }, + { node: NODE_NAMES.RESTORE_CHAT_MEMORY, type: NodeConnectionTypes.AiMemory, index: 0 }, + { node: NODE_NAMES.CLEAR_CHAT_MEMORY, type: NodeConnectionTypes.AiMemory, index: 0 }, ], ], }, @@ -703,7 +710,7 @@ export class ChatHubService { [ { node: NODE_NAMES.CLEAR_CHAT_MEMORY, - type: 'main', + type: NodeConnectionTypes.Main, index: 0, }, ], diff --git a/packages/cli/src/modules/chat-hub/context-limits.ts b/packages/cli/src/modules/chat-hub/context-limits.ts new file mode 100644 index 00000000000..aacf7b87261 --- /dev/null +++ b/packages/cli/src/modules/chat-hub/context-limits.ts @@ -0,0 +1,152 @@ +import type { ChatHubProvider } from '@n8n/api-types'; + +/* eslint-disable @typescript-eslint/naming-convention */ + +// Maximum context window tokens for various models across supported providers. +// Based on a snapshot of model capabilities as of October 2025, with a list of models +// that regular OpenAI / Anthropic / Google API credentials currently have access to at n8n. +// If the limit is set to 0, it means either the model has no defined limit or the information +// is not availabl and no context window trimming is applied. Similarly, if the model used is +// not listed, no limit is applied. +export const maxContextWindowTokens: Record> = { + openai: { + 'chatgpt-4o-latest': 128000, + 'codex-mini-latest': 0, + 'gpt-3.5-turbo': 16392, + 'gpt-3.5-turbo-0125': 16392, + 'gpt-3.5-turbo-1106': 16392, + 'gpt-3.5-turbo-16k': 16392, + 'gpt-4': 8196, + 'gpt-4-0125-preview': 8196, + 'gpt-4-0613': 8196, + 'gpt-4-1106-preview': 8196, + 'gpt-4-turbo': 8196, + 'gpt-4-turbo-2024-04-09': 8196, + 'gpt-4-turbo-preview': 8196, + 'gpt-4.1': 1048576, + 'gpt-4.1-2025-04-14': 1048576, + 'gpt-4.1-mini': 1048576, + 'gpt-4.1-mini-2025-04-14': 1048576, + 'gpt-4.1-nano': 1048576, + 'gpt-4.1-nano-2025-04-14': 1048576, + 'gpt-4o': 128000, + 'gpt-4o-2024-05-13': 128000, + 'gpt-4o-2024-08-06': 128000, + 'gpt-4o-2024-11-20': 128000, + 'gpt-4o-audio-preview': 128000, + 'gpt-4o-audio-preview-2024-10-01': 128000, + 'gpt-4o-audio-preview-2024-12-17': 128000, + 'gpt-4o-audio-preview-2025-06-03': 128000, + 'gpt-4o-mini': 128000, + 'gpt-4o-mini-2024-07-18': 128000, + 'gpt-4o-mini-audio-preview': 128000, + 'gpt-4o-mini-audio-preview-2024-12-17': 128000, + 'gpt-4o-mini-search-preview': 128000, + 'gpt-4o-mini-search-preview-2025-03-11': 128000, + 'gpt-4o-mini-transcribe': 128000, + 'gpt-4o-search-preview': 128000, + 'gpt-4o-search-preview-2025-03-11': 128000, + 'gpt-4o-transcribe': 128000, + 'gpt-4o-transcribe-diarize': 128000, + 'gpt-5': 400000, + 'gpt-5-2025-08-07': 400000, + 'gpt-5-chat-latest': 128000, + 'gpt-5-codex': 400000, + 'gpt-5-mini': 400000, + 'gpt-5-mini-2025-08-07': 400000, + 'gpt-5-nano': 400000, + 'gpt-5-nano-2025-08-07': 400000, + 'gpt-5-pro': 196000, + 'gpt-5-pro-2025-10-06': 196000, + 'gpt-5-search-api': 0, + 'gpt-5-search-api-2025-10-14': 0, + 'gpt-audio': 0, + 'gpt-audio-2025-08-28': 0, + 'gpt-audio-mini': 0, + 'gpt-audio-mini-2025-10-06': 0, + 'gpt-image-1': 0, + 'gpt-image-1-mini': 0, + o1: 200000, + 'o1-2024-12-17': 200000, + 'o1-mini': 200000, + 'o1-mini-2024-09-12': 200000, + 'o1-pro': 200000, + 'o1-pro-2025-03-19': 200000, + o3: 200000, + 'o3-2025-04-16': 200000, + 'o3-mini': 200000, + 'o3-mini-2025-01-31': 200000, + 'o4-mini': 200000, + 'o4-mini-2025-04-16': 200000, + 'o4-mini-deep-research': 0, + 'o4-mini-deep-research-2025-06-26': 0, + }, + anthropic: { + 'claude-haiku-4-5-20251001': 200000, + 'claude-sonnet-4-5-20250929': 200000, + 'claude-opus-4-1-20250805': 200000, + 'claude-opus-4-20250514': 200000, + 'claude-sonnet-4-20250514': 200000, + 'claude-3-7-sonnet-20250219': 200000, + 'claude-3-5-haiku-20241022': 200000, + 'claude-3-haiku-20240307': 200000, + }, + google: { + 'models/aqa': 0, + 'models/gemini-2.0-flash': 1048576, + 'models/gemini-2.0-flash-001': 1048576, + 'models/gemini-2.0-flash-exp': 1048576, + 'models/gemini-2.0-flash-lite': 1048576, + 'models/gemini-2.0-flash-lite-001': 1048576, + 'models/gemini-2.0-flash-lite-preview': 1048576, + 'models/gemini-2.0-flash-lite-preview-02-05': 1048576, + 'models/gemini-2.0-flash-thinking-exp': 32000, + 'models/gemini-2.0-flash-thinking-exp-01-21': 32000, + 'models/gemini-2.0-flash-thinking-exp-1219': 32000, + 'models/gemini-2.0-pro-exp': 2000000, + 'models/gemini-2.0-pro-exp-02-05': 2000000, + 'models/gemini-2.5-computer-use-preview-10-2025': 0, + 'models/gemini-2.5-flash': 1048576, + 'models/gemini-2.5-flash-image': 1048576, + 'models/gemini-2.5-flash-image-preview': 1048576, + 'models/gemini-2.5-flash-lite': 1048576, + 'models/gemini-2.5-flash-lite-preview-06-17': 1048576, + 'models/gemini-2.5-flash-lite-preview-09-2025': 1048576, + 'models/gemini-2.5-flash-preview-05-20': 1048576, + 'models/gemini-2.5-flash-preview-09-2025': 1048576, + 'models/gemini-2.5-flash-preview-tts': 8000, + 'models/gemini-2.5-pro': 1048576, + 'models/gemini-2.5-pro-preview-03-25': 1048576, + 'models/gemini-2.5-pro-preview-05-06': 1048576, + 'models/gemini-2.5-pro-preview-06-05': 1048576, + 'models/gemini-2.5-pro-preview-tts': 8000, + 'models/gemini-exp-1206': 2000000, + 'models/gemini-flash-latest': 1048576, + 'models/gemini-flash-lite-latest': 1048576, + 'models/gemini-pro-latest': 1048576, + 'models/gemini-robotics-er-1.5-preview': 0, + 'models/gemma-3-12b-it': 128000, + 'models/gemma-3-1b-it': 32000, + 'models/gemma-3-27b-it': 128000, + 'models/gemma-3-4b-it': 128000, + 'models/gemma-3n-e2b-it': 32000, + 'models/gemma-3n-e4b-it': 32000, + 'models/imagen-3.0-generate-002': 480, + 'models/imagen-4.0-generate-001': 480, + 'models/imagen-4.0-generate-preview-06-06': 480, + 'models/imagen-4.0-ultra-generate-preview-06-06': 480, + 'models/learnlm-2.0-flash-experimental': 0, + }, +}; + +export const getMaxContextWindowTokens = ( + provider: ChatHubProvider, + model: string, +): number | undefined => { + const limit = maxContextWindowTokens[provider]?.[model] ?? 0; + if (!limit) { + return undefined; + } + + return limit; +};