Many-in-one AI client.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
2.0 KiB

  1. import {
  2. encoding_for_model as encodingForModel,
  3. TiktokenModel,
  4. } from '@dqbd/tiktoken';
  5. import { MessageObject, MessageRole } from './chat';
  6. import { ChatCompletionModel } from './models';
  7. const START_TOKEN = '<|im_start|>' as const;
  8. const END_TOKEN = '<|im_end|>' as const;
  9. const SEPARATOR_TOKEN = '<|im_sep|>' as const;
  10. const generateChatTokenString = (normalizedMessageArray: MessageObject[], model: TiktokenModel) => {
  11. switch (model) {
  12. case ChatCompletionModel.GPT_3_5_TURBO: {
  13. const tokens = normalizedMessageArray
  14. .map((m) => (
  15. `${START_TOKEN}${m.role}\n${m.content}${END_TOKEN}`
  16. ))
  17. .join('\n');
  18. return `${tokens}\n${START_TOKEN}${MessageRole.ASSISTANT}\n`;
  19. }
  20. case ChatCompletionModel.GPT_4:
  21. case ChatCompletionModel.GPT_4_32K: {
  22. const tokens = normalizedMessageArray
  23. .map((m) => (
  24. `${START_TOKEN}${m.role}${SEPARATOR_TOKEN}${m.content}${END_TOKEN}`
  25. ))
  26. .join('');
  27. return `${tokens}${START_TOKEN}${MessageRole.ASSISTANT}${SEPARATOR_TOKEN}`;
  28. }
  29. default:
  30. break;
  31. }
  32. throw new Error('Invalid model.');
  33. };
  34. export const getTokens = (chatTokens: string, model: TiktokenModel) => {
  35. const enc = Object.values(ChatCompletionModel).includes(model as unknown as ChatCompletionModel)
  36. ? encodingForModel(model, {
  37. [START_TOKEN]: 100264,
  38. [END_TOKEN]: 100265,
  39. [SEPARATOR_TOKEN]: 100266,
  40. })
  41. : encodingForModel(model);
  42. const theTokens = enc.encode(chatTokens, 'all');
  43. enc.free();
  44. return theTokens;
  45. };
  46. export const getPromptTokens = (normalizedMessageArray: MessageObject[], model: TiktokenModel) => {
  47. const chatTokens = generateChatTokenString(normalizedMessageArray, model);
  48. return getTokens(chatTokens, model);
  49. };
  50. export interface PromptUsage {
  51. prompt_tokens: number;
  52. total_tokens: number;
  53. }
  54. export interface CompletionUsage extends PromptUsage {
  55. completion_tokens: number;
  56. }
  57. export interface UsageMetadata<U extends PromptUsage> {
  58. usage: U;
  59. }