export function limitMessagesByTokens()

in apps/chat/src/utils/server/chat.ts [21:85]


export function limitMessagesByTokens({
  promptToSend,
  messages,
  limits,
  features,
  tokenizer,
}: {
  promptToSend: string | undefined;
  messages: Message[];
  limits: DialAIEntityModel['limits'];
  features: DialAIEntityModel['features'];
  tokenizer: DialAIEntityModel['tokenizer'];
}): Message[] {
  if (!limits || !limits.maxRequestTokens || features?.truncatePrompt) {
    return messages;
  }

  let calculateTokensSize: (str: string) => number = getBytesTokensSize;
  let tokensPerMessage = 0;

  if (tokenizer && tokenizer.encoding && tokenizer.tokensPerMessage) {
    if (!encodings[tokenizer.encoding]) {
      encodings[tokenizer.encoding] = get_encoding(tokenizer.encoding);
    }
    calculateTokensSize = (str) =>
      tokenizer.encoding && encodings[tokenizer.encoding]
        ? encodings[tokenizer.encoding]!.encode(str).length
        : getBytesTokensSize(str);
    tokensPerMessage = tokenizer.tokensPerMessage;
  }

  const promptToEncode: string = promptToSend ?? '';
  const promptTokensSize = promptToEncode
    ? calculateTokensSize(promptToEncode) + tokensPerMessage
    : 0;

  let fullTokensSize = promptTokensSize;
  let messagesToSend: Message[] = [];

  const length = Math.min(messages.length, 1000);
  for (let i = length - 1; i >= 0; i--) {
    if (!messages[i]) {
      break;
    }
    const currentMessageTokensSize =
      calculateTokensSize(messages[i].content) + tokensPerMessage;

    if (fullTokensSize + currentMessageTokensSize > limits.maxRequestTokens) {
      break;
    }
    fullTokensSize += currentMessageTokensSize;
    messagesToSend = [messages[i], ...messagesToSend];
  }

  if (messagesToSend.length === 0) {
    throw new DialAIError(
      'User sended messages cannot be empty after limit messages by tokens process',
      '',
      '',
      '400',
    );
  }

  return messagesToSend;
}