gpt-tokenizer 4.0.1 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/cjs/BytePairEncodingCore.js +5 -1
  2. package/cjs/BytePairEncodingCore.js.map +1 -1
  3. package/cjs/encodingParams/constants.js +3 -3
  4. package/cjs/encodingParams/constants.js.map +1 -1
  5. package/cjs/utfUtil.d.ts +2 -1
  6. package/cjs/utfUtil.js +8 -1
  7. package/cjs/utfUtil.js.map +1 -1
  8. package/esm/BytePairEncodingCore.js +6 -2
  9. package/esm/BytePairEncodingCore.js.map +1 -1
  10. package/esm/GptEncoding.d.ts +2 -2
  11. package/esm/encoding/cl100k_base.d.ts +1 -1
  12. package/esm/encoding/o200k_base.d.ts +1 -1
  13. package/esm/encoding/o200k_harmony.d.ts +1 -1
  14. package/esm/encoding/p50k_edit.d.ts +1 -1
  15. package/esm/encodingParams/constants.js +3 -3
  16. package/esm/encodingParams/constants.js.map +1 -1
  17. package/esm/model/chat-latest.d.ts +1 -1
  18. package/esm/model/chatgpt-4o-latest.d.ts +1 -1
  19. package/esm/model/codex-mini-latest.d.ts +1 -1
  20. package/esm/model/computer-use-preview-2025-03-11.d.ts +1 -1
  21. package/esm/model/computer-use-preview.d.ts +1 -1
  22. package/esm/model/daybreak-blue-latest.d.ts +1 -1
  23. package/esm/model/daybreak-red-latest.d.ts +1 -1
  24. package/esm/model/gpt-3.5-0301.d.ts +1 -1
  25. package/esm/model/gpt-3.5-turbo-0125.d.ts +1 -1
  26. package/esm/model/gpt-3.5-turbo-0613.d.ts +1 -1
  27. package/esm/model/gpt-3.5-turbo-1106.d.ts +1 -1
  28. package/esm/model/gpt-3.5-turbo-16k-0613.d.ts +1 -1
  29. package/esm/model/gpt-3.5-turbo-instruct.d.ts +1 -1
  30. package/esm/model/gpt-3.5-turbo.d.ts +1 -1
  31. package/esm/model/gpt-3.5.d.ts +1 -1
  32. package/esm/model/gpt-4-0125-preview.d.ts +1 -1
  33. package/esm/model/gpt-4-0314.d.ts +1 -1
  34. package/esm/model/gpt-4-0613.d.ts +1 -1
  35. package/esm/model/gpt-4-1106-preview.d.ts +1 -1
  36. package/esm/model/gpt-4-1106-vision-preview.d.ts +1 -1
  37. package/esm/model/gpt-4-32k.d.ts +1 -1
  38. package/esm/model/gpt-4-turbo-2024-04-09.d.ts +1 -1
  39. package/esm/model/gpt-4-turbo-preview.d.ts +1 -1
  40. package/esm/model/gpt-4-turbo.d.ts +1 -1
  41. package/esm/model/gpt-4.1-2025-04-14.d.ts +1 -1
  42. package/esm/model/gpt-4.1-mini-2025-04-14.d.ts +1 -1
  43. package/esm/model/gpt-4.1-mini.d.ts +1 -1
  44. package/esm/model/gpt-4.1-nano-2025-04-14.d.ts +1 -1
  45. package/esm/model/gpt-4.1-nano.d.ts +1 -1
  46. package/esm/model/gpt-4.1.d.ts +1 -1
  47. package/esm/model/gpt-4.5-preview-2025-02-27.d.ts +1 -1
  48. package/esm/model/gpt-4.5-preview.d.ts +1 -1
  49. package/esm/model/gpt-4.d.ts +1 -1
  50. package/esm/model/gpt-4o-2024-05-13.d.ts +1 -1
  51. package/esm/model/gpt-4o-2024-08-06.d.ts +1 -1
  52. package/esm/model/gpt-4o-2024-11-20.d.ts +1 -1
  53. package/esm/model/gpt-4o-audio-preview-2024-10-01.d.ts +1 -1
  54. package/esm/model/gpt-4o-audio-preview-2024-12-17.d.ts +1 -1
  55. package/esm/model/gpt-4o-audio-preview-2025-06-03.d.ts +1 -1
  56. package/esm/model/gpt-4o-audio-preview.d.ts +1 -1
  57. package/esm/model/gpt-4o-mini-2024-07-18.d.ts +1 -1
  58. package/esm/model/gpt-4o-mini-audio-preview-2024-12-17.d.ts +1 -1
  59. package/esm/model/gpt-4o-mini-audio-preview.d.ts +1 -1
  60. package/esm/model/gpt-4o-mini-search-preview-2025-03-11.d.ts +1 -1
  61. package/esm/model/gpt-4o-mini-search-preview.d.ts +1 -1
  62. package/esm/model/gpt-4o-mini.d.ts +1 -1
  63. package/esm/model/gpt-4o-search-preview-2025-03-11.d.ts +1 -1
  64. package/esm/model/gpt-4o-search-preview.d.ts +1 -1
  65. package/esm/model/gpt-4o.d.ts +1 -1
  66. package/esm/model/gpt-5-2025-08-07.d.ts +1 -1
  67. package/esm/model/gpt-5-chat-latest.d.ts +1 -1
  68. package/esm/model/gpt-5-codex.d.ts +1 -1
  69. package/esm/model/gpt-5-mini-2025-08-07.d.ts +1 -1
  70. package/esm/model/gpt-5-mini.d.ts +1 -1
  71. package/esm/model/gpt-5-nano-2025-08-07.d.ts +1 -1
  72. package/esm/model/gpt-5-nano.d.ts +1 -1
  73. package/esm/model/gpt-5-pro-2025-10-06.d.ts +1 -1
  74. package/esm/model/gpt-5-pro.d.ts +1 -1
  75. package/esm/model/gpt-5.1-2025-11-13.d.ts +1 -1
  76. package/esm/model/gpt-5.1-chat-latest.d.ts +1 -1
  77. package/esm/model/gpt-5.1-codex-max.d.ts +1 -1
  78. package/esm/model/gpt-5.1-codex-mini.d.ts +1 -1
  79. package/esm/model/gpt-5.1-codex.d.ts +1 -1
  80. package/esm/model/gpt-5.1.d.ts +1 -1
  81. package/esm/model/gpt-5.2-2025-12-11.d.ts +1 -1
  82. package/esm/model/gpt-5.2-chat-latest.d.ts +1 -1
  83. package/esm/model/gpt-5.2-codex.d.ts +1 -1
  84. package/esm/model/gpt-5.2-pro-2025-12-11.d.ts +1 -1
  85. package/esm/model/gpt-5.2-pro.d.ts +1 -1
  86. package/esm/model/gpt-5.2.d.ts +1 -1
  87. package/esm/model/gpt-5.3-chat-latest.d.ts +1 -1
  88. package/esm/model/gpt-5.3-codex.d.ts +1 -1
  89. package/esm/model/gpt-5.4-2026-03-05.d.ts +1 -1
  90. package/esm/model/gpt-5.4-mini-2026-03-17.d.ts +1 -1
  91. package/esm/model/gpt-5.4-mini.d.ts +1 -1
  92. package/esm/model/gpt-5.4-nano-2026-03-17.d.ts +1 -1
  93. package/esm/model/gpt-5.4-nano.d.ts +1 -1
  94. package/esm/model/gpt-5.4-pro-2026-03-05.d.ts +1 -1
  95. package/esm/model/gpt-5.4-pro.d.ts +1 -1
  96. package/esm/model/gpt-5.4.d.ts +1 -1
  97. package/esm/model/gpt-5.5-2026-04-23.d.ts +1 -1
  98. package/esm/model/gpt-5.5-pro-2026-04-23.d.ts +1 -1
  99. package/esm/model/gpt-5.5-pro.d.ts +1 -1
  100. package/esm/model/gpt-5.5.d.ts +1 -1
  101. package/esm/model/gpt-5.6-cyber.d.ts +1 -1
  102. package/esm/model/gpt-5.6-luna.d.ts +1 -1
  103. package/esm/model/gpt-5.6-sol.d.ts +1 -1
  104. package/esm/model/gpt-5.6-terra.d.ts +1 -1
  105. package/esm/model/gpt-5.d.ts +1 -1
  106. package/esm/model/gpt-audio-1.5.d.ts +1 -1
  107. package/esm/model/gpt-audio-2025-08-28.d.ts +1 -1
  108. package/esm/model/gpt-audio-mini-2025-10-06.d.ts +1 -1
  109. package/esm/model/gpt-audio-mini-2025-12-15.d.ts +1 -1
  110. package/esm/model/gpt-audio-mini.d.ts +1 -1
  111. package/esm/model/gpt-audio.d.ts +1 -1
  112. package/esm/model/gpt-image-1.d.ts +1 -1
  113. package/esm/model/gpt-oss-120b.d.ts +1 -1
  114. package/esm/model/gpt-oss-20b.d.ts +1 -1
  115. package/esm/model/o1-2024-12-17.d.ts +1 -1
  116. package/esm/model/o1-mini-2024-09-12.d.ts +1 -1
  117. package/esm/model/o1-mini.d.ts +1 -1
  118. package/esm/model/o1-preview-2024-09-12.d.ts +1 -1
  119. package/esm/model/o1-preview.d.ts +1 -1
  120. package/esm/model/o1-pro-2025-03-19.d.ts +1 -1
  121. package/esm/model/o1-pro.d.ts +1 -1
  122. package/esm/model/o1.d.ts +1 -1
  123. package/esm/model/o3-2025-04-16.d.ts +1 -1
  124. package/esm/model/o3-deep-research-2025-06-26.d.ts +1 -1
  125. package/esm/model/o3-deep-research.d.ts +1 -1
  126. package/esm/model/o3-mini-2025-01-31.d.ts +1 -1
  127. package/esm/model/o3-mini.d.ts +1 -1
  128. package/esm/model/o3-pro-2025-06-10.d.ts +1 -1
  129. package/esm/model/o3-pro.d.ts +1 -1
  130. package/esm/model/o3.d.ts +1 -1
  131. package/esm/model/o4-mini-2025-04-16.d.ts +1 -1
  132. package/esm/model/o4-mini-deep-research-2025-06-26.d.ts +1 -1
  133. package/esm/model/o4-mini-deep-research.d.ts +1 -1
  134. package/esm/model/o4-mini.d.ts +1 -1
  135. package/esm/utfUtil.d.ts +2 -1
  136. package/esm/utfUtil.js +8 -2
  137. package/esm/utfUtil.js.map +1 -1
  138. package/package.json +1 -1
  139. package/src/BytePairEncodingCore.ts +18 -2
  140. package/src/encodingParams/constants.ts +7 -3
  141. package/src/unicodeWhiteSpace.test.ts +247 -0
  142. package/src/utfUtil.ts +12 -1
@@ -5,7 +5,7 @@ import { EncodeOptions, GptEncoding } from "../GptEncoding.js";
5
5
  import { EndOfPrompt, EndOfText, FimMiddle, FimPrefix, FimSuffix, HarmonyCall, HarmonyChannel, HarmonyConstrain, HarmonyEnd, HarmonyMessage, HarmonyReturn, HarmonyStart, HarmonyStartOfText, ImEnd, ImSep, ImStart } from "../specialTokens.js";
6
6
  //#region src/model/o4-mini-deep-research.d.ts
7
7
  declare const api: GptEncoding;
8
- declare const decode: (inputTokensToDecode: Iterable<number>) => string, decodeAsyncGenerator: (inputTokensToDecode: AsyncIterable<number>) => AsyncGenerator<string, void>, decodeGenerator: (inputTokensToDecode: Iterable<number>) => Generator<string, void, void>, encode: (lineToEncode: string, encodeOptions?: EncodeOptions) => number[], encodeGenerator: (lineToEncode: string, encodeOptions?: EncodeOptions) => Generator<number[], number, undefined>, isWithinTokenLimit: (input: string | Iterable<ChatMessage>, tokenLimit: number, encodeOptions?: EncodeOptions) => false | number, countTokens: (input: string | Iterable<ChatMessage>, encodeOptions?: EncodeOptions) => number, encodeChat: (chat: readonly ChatMessage[], model?: "gpt-3.5-0301" | "gpt-3.5" | "gpt-3.5-turbo-0613" | "gpt-4-1106-preview" | "gpt-4-32k" | "gpt-2" | "gpt2" | "text-ada-001" | "text-babbage-001" | "text-curie-001" | "text-davinci-001" | "text-davinci-002" | "text-davinci-003" | "ada" | "babbage" | "curie" | "davinci" | "code-davinci-001" | "code-davinci-002" | "davinci-codex" | "code-davinci-edit-001" | "code-cushman-001" | "code-cushman-002" | "cushman-codex" | "code-search-ada-code-001" | "code-search-ada-text-001" | "text-davinci-edit-001" | "text-similarity-ada-001" | "text-search-ada-doc-001" | "text-search-ada-query-001" | "text-similarity-babbage-001" | "text-search-babbage-doc-001" | "text-search-babbage-query-001" | "code-search-babbage-code-001" | "code-search-babbage-text-001" | "text-similarity-curie-001" | "text-search-curie-doc-001" | "text-search-curie-query-001" | "text-similarity-davinci-001" | "text-search-davinci-doc-001" | "text-search-davinci-query-001" | "babbage-002" | "chat-latest" | "chatgpt-4o-latest" | "chatgpt-image-latest" | "codex-mini-latest" | "computer-use-preview-2025-03-11" | "computer-use-preview" | "dall-e-2" | "dall-e-3" | "davinci-002" | "gpt-5.6-sol" | "daybreak-blue-latest" | "gpt-5.6-cyber" | "daybreak-red-latest" | "gpt-3.5-turbo-16k-0613" | "gpt-3.5-turbo-instruct" | "gpt-3.5-turbo-0125" | "gpt-3.5-turbo-1106" | "gpt-3.5-turbo" | "gpt-4-0125-preview" | "gpt-4-1106-vision-preview" | "gpt-4-turbo-preview" | "gpt-4-turbo-2024-04-09" | "gpt-4-turbo" | "gpt-4.1-mini-2025-04-14" | "gpt-4.1-mini" | "gpt-4.1-nano-2025-04-14" | "gpt-4.1-nano" | "gpt-4.1-2025-04-14" | "gpt-4.1" | "gpt-4.5-preview-2025-02-27" | "gpt-4.5-preview" | "gpt-4-0613" | "gpt-4-0314" | "gpt-4" | "gpt-4o-audio-preview-2025-06-03" | "gpt-4o-audio-preview-2024-12-17" | "gpt-4o-audio-preview-2024-10-01" | "gpt-4o-audio-preview" | "gpt-4o-mini-audio-preview-2024-12-17" | "gpt-4o-mini-audio-preview" | "gpt-4o-mini-realtime-preview-2024-12-17" | "gpt-4o-mini-realtime-preview" | "gpt-4o-mini-search-preview-2025-03-11" | "gpt-4o-mini-search-preview" | "gpt-4o-mini-transcribe-2025-03-20" | "gpt-4o-mini-transcribe-2025-12-15" | "gpt-4o-mini-transcribe" | "gpt-4o-mini-tts-2025-03-20" | "gpt-4o-mini-tts-2025-12-15" | "gpt-4o-mini-tts" | "gpt-4o-mini-2024-07-18" | "gpt-4o-mini" | "gpt-4o-realtime-preview-2025-06-03" | "gpt-4o-realtime-preview-2024-12-17" | "gpt-4o-realtime-preview-2024-10-01" | "gpt-4o-realtime-preview" | "gpt-4o-search-preview-2025-03-11" | "gpt-4o-search-preview" | "gpt-4o-transcribe-diarize" | "gpt-4o-transcribe" | "gpt-4o-2024-11-20" | "gpt-4o-2024-08-06" | "gpt-4o-2024-05-13" | "gpt-4o" | "gpt-5-chat-latest" | "gpt-5-codex" | "gpt-5-mini-2025-08-07" | "gpt-5-mini" | "gpt-5-nano-2025-08-07" | "gpt-5-nano" | "gpt-5-pro-2025-10-06" | "gpt-5-pro" | "gpt-5.1-chat-latest" | "gpt-5.1-codex-max" | "gpt-5.1-codex-mini" | "gpt-5.1-codex" | "gpt-5.1-2025-11-13" | "gpt-5.1" | "gpt-5.2-chat-latest" | "gpt-5.2-codex" | "gpt-5.2-pro-2025-12-11" | "gpt-5.2-pro" | "gpt-5.2-2025-12-11" | "gpt-5.2" | "gpt-5.3-chat-latest" | "gpt-5.3-codex" | "gpt-5.4-mini-2026-03-17" | "gpt-5.4-mini" | "gpt-5.4-nano-2026-03-17" | "gpt-5.4-nano" | "gpt-5.4-pro-2026-03-05" | "gpt-5.4-pro" | "gpt-5.4-2026-03-05" | "gpt-5.4" | "gpt-5.5-pro-2026-04-23" | "gpt-5.5-pro" | "gpt-5.5-2026-04-23" | "gpt-5.5" | "gpt-5.6-luna" | "gpt-5.6-terra" | "gpt-5-2025-08-07" | "gpt-5" | "gpt-audio-1.5" | "gpt-audio-mini-2025-10-06" | "gpt-audio-mini-2025-12-15" | "gpt-audio-mini" | "gpt-audio-2025-08-28" | "gpt-audio" | "gpt-image-1-mini" | "gpt-image-1.5-2025-12-16" | "gpt-image-1.5" | "gpt-image-1" | "gpt-image-2-2026-04-21" | "gpt-image-2" | "gpt-live-transcribe" | "gpt-oss-120b" | "gpt-oss-20b" | "gpt-realtime-1.5" | "gpt-realtime-2.1-mini" | "gpt-realtime-2.1" | "gpt-realtime-2" | "gpt-realtime-mini-2025-10-06" | "gpt-realtime-mini-2025-12-15" | "gpt-realtime-mini" | "gpt-realtime-translate" | "gpt-realtime-whisper" | "gpt-realtime-2025-08-28" | "gpt-realtime" | "gpt-transcribe" | "o1-mini-2024-09-12" | "o1-mini" | "o1-preview-2024-09-12" | "o1-preview" | "o1-pro-2025-03-19" | "o1-pro" | "o1-2024-12-17" | "o1" | "o3-deep-research-2025-06-26" | "o3-deep-research" | "o3-mini-2025-01-31" | "o3-mini" | "o3-pro-2025-06-10" | "o3-pro" | "o3-2025-04-16" | "o3" | "o4-mini-deep-research-2025-06-26" | "o4-mini-deep-research" | "o4-mini-2025-04-16" | "o4-mini" | "omni-moderation-2024-09-26" | "omni-moderation-latest" | "sora-2-pro-2025-10-06" | "sora-2-pro" | "sora-2-2025-12-08" | "sora-2-2025-10-06" | "sora-2" | "text-embedding-3-large" | "text-embedding-3-small" | "text-embedding-ada-002" | "text-moderation-007" | "text-moderation-latest" | "text-moderation-stable" | "tts-1-hd" | "tts-1" | "whisper-1" | undefined, encodeOptions?: EncodeOptions & EncodeChatOptions) => number[], encodeChatGenerator: (chat: Iterable<ChatMessage>, model?: "gpt-3.5-0301" | "gpt-3.5" | "gpt-3.5-turbo-0613" | "gpt-4-1106-preview" | "gpt-4-32k" | "gpt-2" | "gpt2" | "text-ada-001" | "text-babbage-001" | "text-curie-001" | "text-davinci-001" | "text-davinci-002" | "text-davinci-003" | "ada" | "babbage" | "curie" | "davinci" | "code-davinci-001" | "code-davinci-002" | "davinci-codex" | "code-davinci-edit-001" | "code-cushman-001" | "code-cushman-002" | "cushman-codex" | "code-search-ada-code-001" | "code-search-ada-text-001" | "text-davinci-edit-001" | "text-similarity-ada-001" | "text-search-ada-doc-001" | "text-search-ada-query-001" | "text-similarity-babbage-001" | "text-search-babbage-doc-001" | "text-search-babbage-query-001" | "code-search-babbage-code-001" | "code-search-babbage-text-001" | "text-similarity-curie-001" | "text-search-curie-doc-001" | "text-search-curie-query-001" | "text-similarity-davinci-001" | "text-search-davinci-doc-001" | "text-search-davinci-query-001" | "babbage-002" | "chat-latest" | "chatgpt-4o-latest" | "chatgpt-image-latest" | "codex-mini-latest" | "computer-use-preview-2025-03-11" | "computer-use-preview" | "dall-e-2" | "dall-e-3" | "davinci-002" | "gpt-5.6-sol" | "daybreak-blue-latest" | "gpt-5.6-cyber" | "daybreak-red-latest" | "gpt-3.5-turbo-16k-0613" | "gpt-3.5-turbo-instruct" | "gpt-3.5-turbo-0125" | "gpt-3.5-turbo-1106" | "gpt-3.5-turbo" | "gpt-4-0125-preview" | "gpt-4-1106-vision-preview" | "gpt-4-turbo-preview" | "gpt-4-turbo-2024-04-09" | "gpt-4-turbo" | "gpt-4.1-mini-2025-04-14" | "gpt-4.1-mini" | "gpt-4.1-nano-2025-04-14" | "gpt-4.1-nano" | "gpt-4.1-2025-04-14" | "gpt-4.1" | "gpt-4.5-preview-2025-02-27" | "gpt-4.5-preview" | "gpt-4-0613" | "gpt-4-0314" | "gpt-4" | "gpt-4o-audio-preview-2025-06-03" | "gpt-4o-audio-preview-2024-12-17" | "gpt-4o-audio-preview-2024-10-01" | "gpt-4o-audio-preview" | "gpt-4o-mini-audio-preview-2024-12-17" | "gpt-4o-mini-audio-preview" | "gpt-4o-mini-realtime-preview-2024-12-17" | "gpt-4o-mini-realtime-preview" | "gpt-4o-mini-search-preview-2025-03-11" | "gpt-4o-mini-search-preview" | "gpt-4o-mini-transcribe-2025-03-20" | "gpt-4o-mini-transcribe-2025-12-15" | "gpt-4o-mini-transcribe" | "gpt-4o-mini-tts-2025-03-20" | "gpt-4o-mini-tts-2025-12-15" | "gpt-4o-mini-tts" | "gpt-4o-mini-2024-07-18" | "gpt-4o-mini" | "gpt-4o-realtime-preview-2025-06-03" | "gpt-4o-realtime-preview-2024-12-17" | "gpt-4o-realtime-preview-2024-10-01" | "gpt-4o-realtime-preview" | "gpt-4o-search-preview-2025-03-11" | "gpt-4o-search-preview" | "gpt-4o-transcribe-diarize" | "gpt-4o-transcribe" | "gpt-4o-2024-11-20" | "gpt-4o-2024-08-06" | "gpt-4o-2024-05-13" | "gpt-4o" | "gpt-5-chat-latest" | "gpt-5-codex" | "gpt-5-mini-2025-08-07" | "gpt-5-mini" | "gpt-5-nano-2025-08-07" | "gpt-5-nano" | "gpt-5-pro-2025-10-06" | "gpt-5-pro" | "gpt-5.1-chat-latest" | "gpt-5.1-codex-max" | "gpt-5.1-codex-mini" | "gpt-5.1-codex" | "gpt-5.1-2025-11-13" | "gpt-5.1" | "gpt-5.2-chat-latest" | "gpt-5.2-codex" | "gpt-5.2-pro-2025-12-11" | "gpt-5.2-pro" | "gpt-5.2-2025-12-11" | "gpt-5.2" | "gpt-5.3-chat-latest" | "gpt-5.3-codex" | "gpt-5.4-mini-2026-03-17" | "gpt-5.4-mini" | "gpt-5.4-nano-2026-03-17" | "gpt-5.4-nano" | "gpt-5.4-pro-2026-03-05" | "gpt-5.4-pro" | "gpt-5.4-2026-03-05" | "gpt-5.4" | "gpt-5.5-pro-2026-04-23" | "gpt-5.5-pro" | "gpt-5.5-2026-04-23" | "gpt-5.5" | "gpt-5.6-luna" | "gpt-5.6-terra" | "gpt-5-2025-08-07" | "gpt-5" | "gpt-audio-1.5" | "gpt-audio-mini-2025-10-06" | "gpt-audio-mini-2025-12-15" | "gpt-audio-mini" | "gpt-audio-2025-08-28" | "gpt-audio" | "gpt-image-1-mini" | "gpt-image-1.5-2025-12-16" | "gpt-image-1.5" | "gpt-image-1" | "gpt-image-2-2026-04-21" | "gpt-image-2" | "gpt-live-transcribe" | "gpt-oss-120b" | "gpt-oss-20b" | "gpt-realtime-1.5" | "gpt-realtime-2.1-mini" | "gpt-realtime-2.1" | "gpt-realtime-2" | "gpt-realtime-mini-2025-10-06" | "gpt-realtime-mini-2025-12-15" | "gpt-realtime-mini" | "gpt-realtime-translate" | "gpt-realtime-whisper" | "gpt-realtime-2025-08-28" | "gpt-realtime" | "gpt-transcribe" | "o1-mini-2024-09-12" | "o1-mini" | "o1-preview-2024-09-12" | "o1-preview" | "o1-pro-2025-03-19" | "o1-pro" | "o1-2024-12-17" | "o1" | "o3-deep-research-2025-06-26" | "o3-deep-research" | "o3-mini-2025-01-31" | "o3-mini" | "o3-pro-2025-06-10" | "o3-pro" | "o3-2025-04-16" | "o3" | "o4-mini-deep-research-2025-06-26" | "o4-mini-deep-research" | "o4-mini-2025-04-16" | "o4-mini" | "omni-moderation-2024-09-26" | "omni-moderation-latest" | "sora-2-pro-2025-10-06" | "sora-2-pro" | "sora-2-2025-12-08" | "sora-2-2025-10-06" | "sora-2" | "text-embedding-3-large" | "text-embedding-3-small" | "text-embedding-ada-002" | "text-moderation-007" | "text-moderation-latest" | "text-moderation-stable" | "tts-1-hd" | "tts-1" | "whisper-1" | undefined, encodeOptions?: EncodeOptions & EncodeChatOptions) => Generator<number[], void, undefined>, vocabularySize: number, setMergeCacheSize: (size: number) => void, clearMergeCache: () => void, estimateCost: (tokenCount: number, modelSpec?: ModelSpec | undefined) => PriceData;
8
+ declare const decode: (inputTokensToDecode: Iterable<number>) => string, decodeAsyncGenerator: (inputTokensToDecode: AsyncIterable<number>) => AsyncGenerator<string, void>, decodeGenerator: (inputTokensToDecode: Iterable<number>) => Generator<string, void, void>, encode: (lineToEncode: string, encodeOptions?: EncodeOptions) => number[], encodeGenerator: (lineToEncode: string, encodeOptions?: EncodeOptions) => Generator<number[], number, undefined>, isWithinTokenLimit: (input: string | Iterable<ChatMessage>, tokenLimit: number, encodeOptions?: EncodeOptions) => false | number, countTokens: (input: string | Iterable<ChatMessage>, encodeOptions?: EncodeOptions) => number, encodeChat: (chat: readonly ChatMessage[], model?: "gpt2" | "gpt-3.5-0301" | "gpt-3.5" | "gpt-3.5-turbo-0613" | "gpt-4-1106-preview" | "gpt-4-32k" | "gpt-2" | "text-ada-001" | "text-babbage-001" | "text-curie-001" | "text-davinci-001" | "text-davinci-002" | "text-davinci-003" | "ada" | "babbage" | "curie" | "davinci" | "code-davinci-001" | "code-davinci-002" | "davinci-codex" | "code-davinci-edit-001" | "code-cushman-001" | "code-cushman-002" | "cushman-codex" | "code-search-ada-code-001" | "code-search-ada-text-001" | "text-davinci-edit-001" | "text-similarity-ada-001" | "text-search-ada-doc-001" | "text-search-ada-query-001" | "text-similarity-babbage-001" | "text-search-babbage-doc-001" | "text-search-babbage-query-001" | "code-search-babbage-code-001" | "code-search-babbage-text-001" | "text-similarity-curie-001" | "text-search-curie-doc-001" | "text-search-curie-query-001" | "text-similarity-davinci-001" | "text-search-davinci-doc-001" | "text-search-davinci-query-001" | "babbage-002" | "chat-latest" | "chatgpt-4o-latest" | "chatgpt-image-latest" | "codex-mini-latest" | "computer-use-preview-2025-03-11" | "computer-use-preview" | "dall-e-2" | "dall-e-3" | "davinci-002" | "gpt-5.6-sol" | "daybreak-blue-latest" | "gpt-5.6-cyber" | "daybreak-red-latest" | "gpt-3.5-turbo-16k-0613" | "gpt-3.5-turbo-instruct" | "gpt-3.5-turbo-0125" | "gpt-3.5-turbo-1106" | "gpt-3.5-turbo" | "gpt-4-0125-preview" | "gpt-4-1106-vision-preview" | "gpt-4-turbo-preview" | "gpt-4-turbo-2024-04-09" | "gpt-4-turbo" | "gpt-4.1-mini-2025-04-14" | "gpt-4.1-mini" | "gpt-4.1-nano-2025-04-14" | "gpt-4.1-nano" | "gpt-4.1-2025-04-14" | "gpt-4.1" | "gpt-4.5-preview-2025-02-27" | "gpt-4.5-preview" | "gpt-4-0613" | "gpt-4-0314" | "gpt-4" | "gpt-4o-audio-preview-2025-06-03" | "gpt-4o-audio-preview-2024-12-17" | "gpt-4o-audio-preview-2024-10-01" | "gpt-4o-audio-preview" | "gpt-4o-mini-audio-preview-2024-12-17" | "gpt-4o-mini-audio-preview" | "gpt-4o-mini-realtime-preview-2024-12-17" | "gpt-4o-mini-realtime-preview" | "gpt-4o-mini-search-preview-2025-03-11" | "gpt-4o-mini-search-preview" | "gpt-4o-mini-transcribe-2025-03-20" | "gpt-4o-mini-transcribe-2025-12-15" | "gpt-4o-mini-transcribe" | "gpt-4o-mini-tts-2025-03-20" | "gpt-4o-mini-tts-2025-12-15" | "gpt-4o-mini-tts" | "gpt-4o-mini-2024-07-18" | "gpt-4o-mini" | "gpt-4o-realtime-preview-2025-06-03" | "gpt-4o-realtime-preview-2024-12-17" | "gpt-4o-realtime-preview-2024-10-01" | "gpt-4o-realtime-preview" | "gpt-4o-search-preview-2025-03-11" | "gpt-4o-search-preview" | "gpt-4o-transcribe-diarize" | "gpt-4o-transcribe" | "gpt-4o-2024-11-20" | "gpt-4o-2024-08-06" | "gpt-4o-2024-05-13" | "gpt-4o" | "gpt-5-chat-latest" | "gpt-5-codex" | "gpt-5-mini-2025-08-07" | "gpt-5-mini" | "gpt-5-nano-2025-08-07" | "gpt-5-nano" | "gpt-5-pro-2025-10-06" | "gpt-5-pro" | "gpt-5.1-chat-latest" | "gpt-5.1-codex-max" | "gpt-5.1-codex-mini" | "gpt-5.1-codex" | "gpt-5.1-2025-11-13" | "gpt-5.1" | "gpt-5.2-chat-latest" | "gpt-5.2-codex" | "gpt-5.2-pro-2025-12-11" | "gpt-5.2-pro" | "gpt-5.2-2025-12-11" | "gpt-5.2" | "gpt-5.3-chat-latest" | "gpt-5.3-codex" | "gpt-5.4-mini-2026-03-17" | "gpt-5.4-mini" | "gpt-5.4-nano-2026-03-17" | "gpt-5.4-nano" | "gpt-5.4-pro-2026-03-05" | "gpt-5.4-pro" | "gpt-5.4-2026-03-05" | "gpt-5.4" | "gpt-5.5-pro-2026-04-23" | "gpt-5.5-pro" | "gpt-5.5-2026-04-23" | "gpt-5.5" | "gpt-5.6-luna" | "gpt-5.6-terra" | "gpt-5-2025-08-07" | "gpt-5" | "gpt-audio-1.5" | "gpt-audio-mini-2025-10-06" | "gpt-audio-mini-2025-12-15" | "gpt-audio-mini" | "gpt-audio-2025-08-28" | "gpt-audio" | "gpt-image-1-mini" | "gpt-image-1.5-2025-12-16" | "gpt-image-1.5" | "gpt-image-1" | "gpt-image-2-2026-04-21" | "gpt-image-2" | "gpt-live-transcribe" | "gpt-oss-120b" | "gpt-oss-20b" | "gpt-realtime-1.5" | "gpt-realtime-2.1-mini" | "gpt-realtime-2.1" | "gpt-realtime-2" | "gpt-realtime-mini-2025-10-06" | "gpt-realtime-mini-2025-12-15" | "gpt-realtime-mini" | "gpt-realtime-translate" | "gpt-realtime-whisper" | "gpt-realtime-2025-08-28" | "gpt-realtime" | "gpt-transcribe" | "o1-mini-2024-09-12" | "o1-mini" | "o1-preview-2024-09-12" | "o1-preview" | "o1-pro-2025-03-19" | "o1-pro" | "o1-2024-12-17" | "o1" | "o3-deep-research-2025-06-26" | "o3-deep-research" | "o3-mini-2025-01-31" | "o3-mini" | "o3-pro-2025-06-10" | "o3-pro" | "o3-2025-04-16" | "o3" | "o4-mini-deep-research-2025-06-26" | "o4-mini-deep-research" | "o4-mini-2025-04-16" | "o4-mini" | "omni-moderation-2024-09-26" | "omni-moderation-latest" | "sora-2-pro-2025-10-06" | "sora-2-pro" | "sora-2-2025-12-08" | "sora-2-2025-10-06" | "sora-2" | "text-embedding-3-large" | "text-embedding-3-small" | "text-embedding-ada-002" | "text-moderation-007" | "text-moderation-latest" | "text-moderation-stable" | "tts-1-hd" | "tts-1" | "whisper-1" | undefined, encodeOptions?: EncodeOptions & EncodeChatOptions) => number[], encodeChatGenerator: (chat: Iterable<ChatMessage>, model?: "gpt2" | "gpt-3.5-0301" | "gpt-3.5" | "gpt-3.5-turbo-0613" | "gpt-4-1106-preview" | "gpt-4-32k" | "gpt-2" | "text-ada-001" | "text-babbage-001" | "text-curie-001" | "text-davinci-001" | "text-davinci-002" | "text-davinci-003" | "ada" | "babbage" | "curie" | "davinci" | "code-davinci-001" | "code-davinci-002" | "davinci-codex" | "code-davinci-edit-001" | "code-cushman-001" | "code-cushman-002" | "cushman-codex" | "code-search-ada-code-001" | "code-search-ada-text-001" | "text-davinci-edit-001" | "text-similarity-ada-001" | "text-search-ada-doc-001" | "text-search-ada-query-001" | "text-similarity-babbage-001" | "text-search-babbage-doc-001" | "text-search-babbage-query-001" | "code-search-babbage-code-001" | "code-search-babbage-text-001" | "text-similarity-curie-001" | "text-search-curie-doc-001" | "text-search-curie-query-001" | "text-similarity-davinci-001" | "text-search-davinci-doc-001" | "text-search-davinci-query-001" | "babbage-002" | "chat-latest" | "chatgpt-4o-latest" | "chatgpt-image-latest" | "codex-mini-latest" | "computer-use-preview-2025-03-11" | "computer-use-preview" | "dall-e-2" | "dall-e-3" | "davinci-002" | "gpt-5.6-sol" | "daybreak-blue-latest" | "gpt-5.6-cyber" | "daybreak-red-latest" | "gpt-3.5-turbo-16k-0613" | "gpt-3.5-turbo-instruct" | "gpt-3.5-turbo-0125" | "gpt-3.5-turbo-1106" | "gpt-3.5-turbo" | "gpt-4-0125-preview" | "gpt-4-1106-vision-preview" | "gpt-4-turbo-preview" | "gpt-4-turbo-2024-04-09" | "gpt-4-turbo" | "gpt-4.1-mini-2025-04-14" | "gpt-4.1-mini" | "gpt-4.1-nano-2025-04-14" | "gpt-4.1-nano" | "gpt-4.1-2025-04-14" | "gpt-4.1" | "gpt-4.5-preview-2025-02-27" | "gpt-4.5-preview" | "gpt-4-0613" | "gpt-4-0314" | "gpt-4" | "gpt-4o-audio-preview-2025-06-03" | "gpt-4o-audio-preview-2024-12-17" | "gpt-4o-audio-preview-2024-10-01" | "gpt-4o-audio-preview" | "gpt-4o-mini-audio-preview-2024-12-17" | "gpt-4o-mini-audio-preview" | "gpt-4o-mini-realtime-preview-2024-12-17" | "gpt-4o-mini-realtime-preview" | "gpt-4o-mini-search-preview-2025-03-11" | "gpt-4o-mini-search-preview" | "gpt-4o-mini-transcribe-2025-03-20" | "gpt-4o-mini-transcribe-2025-12-15" | "gpt-4o-mini-transcribe" | "gpt-4o-mini-tts-2025-03-20" | "gpt-4o-mini-tts-2025-12-15" | "gpt-4o-mini-tts" | "gpt-4o-mini-2024-07-18" | "gpt-4o-mini" | "gpt-4o-realtime-preview-2025-06-03" | "gpt-4o-realtime-preview-2024-12-17" | "gpt-4o-realtime-preview-2024-10-01" | "gpt-4o-realtime-preview" | "gpt-4o-search-preview-2025-03-11" | "gpt-4o-search-preview" | "gpt-4o-transcribe-diarize" | "gpt-4o-transcribe" | "gpt-4o-2024-11-20" | "gpt-4o-2024-08-06" | "gpt-4o-2024-05-13" | "gpt-4o" | "gpt-5-chat-latest" | "gpt-5-codex" | "gpt-5-mini-2025-08-07" | "gpt-5-mini" | "gpt-5-nano-2025-08-07" | "gpt-5-nano" | "gpt-5-pro-2025-10-06" | "gpt-5-pro" | "gpt-5.1-chat-latest" | "gpt-5.1-codex-max" | "gpt-5.1-codex-mini" | "gpt-5.1-codex" | "gpt-5.1-2025-11-13" | "gpt-5.1" | "gpt-5.2-chat-latest" | "gpt-5.2-codex" | "gpt-5.2-pro-2025-12-11" | "gpt-5.2-pro" | "gpt-5.2-2025-12-11" | "gpt-5.2" | "gpt-5.3-chat-latest" | "gpt-5.3-codex" | "gpt-5.4-mini-2026-03-17" | "gpt-5.4-mini" | "gpt-5.4-nano-2026-03-17" | "gpt-5.4-nano" | "gpt-5.4-pro-2026-03-05" | "gpt-5.4-pro" | "gpt-5.4-2026-03-05" | "gpt-5.4" | "gpt-5.5-pro-2026-04-23" | "gpt-5.5-pro" | "gpt-5.5-2026-04-23" | "gpt-5.5" | "gpt-5.6-luna" | "gpt-5.6-terra" | "gpt-5-2025-08-07" | "gpt-5" | "gpt-audio-1.5" | "gpt-audio-mini-2025-10-06" | "gpt-audio-mini-2025-12-15" | "gpt-audio-mini" | "gpt-audio-2025-08-28" | "gpt-audio" | "gpt-image-1-mini" | "gpt-image-1.5-2025-12-16" | "gpt-image-1.5" | "gpt-image-1" | "gpt-image-2-2026-04-21" | "gpt-image-2" | "gpt-live-transcribe" | "gpt-oss-120b" | "gpt-oss-20b" | "gpt-realtime-1.5" | "gpt-realtime-2.1-mini" | "gpt-realtime-2.1" | "gpt-realtime-2" | "gpt-realtime-mini-2025-10-06" | "gpt-realtime-mini-2025-12-15" | "gpt-realtime-mini" | "gpt-realtime-translate" | "gpt-realtime-whisper" | "gpt-realtime-2025-08-28" | "gpt-realtime" | "gpt-transcribe" | "o1-mini-2024-09-12" | "o1-mini" | "o1-preview-2024-09-12" | "o1-preview" | "o1-pro-2025-03-19" | "o1-pro" | "o1-2024-12-17" | "o1" | "o3-deep-research-2025-06-26" | "o3-deep-research" | "o3-mini-2025-01-31" | "o3-mini" | "o3-pro-2025-06-10" | "o3-pro" | "o3-2025-04-16" | "o3" | "o4-mini-deep-research-2025-06-26" | "o4-mini-deep-research" | "o4-mini-2025-04-16" | "o4-mini" | "omni-moderation-2024-09-26" | "omni-moderation-latest" | "sora-2-pro-2025-10-06" | "sora-2-pro" | "sora-2-2025-12-08" | "sora-2-2025-10-06" | "sora-2" | "text-embedding-3-large" | "text-embedding-3-small" | "text-embedding-ada-002" | "text-moderation-007" | "text-moderation-latest" | "text-moderation-stable" | "tts-1-hd" | "tts-1" | "whisper-1" | undefined, encodeOptions?: EncodeOptions & EncodeChatOptions) => Generator<number[], void, undefined>, vocabularySize: number, setMergeCacheSize: (size: number) => void, clearMergeCache: () => void, estimateCost: (tokenCount: number, modelSpec?: ModelSpec | undefined) => PriceData;
9
9
  //#endregion
10
10
  export { ALL_SPECIAL_TOKENS, DEFAULT_MERGE_CACHE_SIZE, EndOfPrompt, EndOfText, FimMiddle, FimPrefix, FimSuffix, HarmonyCall, HarmonyChannel, HarmonyConstrain, HarmonyEnd, HarmonyMessage, HarmonyReturn, HarmonyStart, HarmonyStartOfText, ImEnd, ImSep, ImStart, clearMergeCache, countTokens, decode, decodeAsyncGenerator, decodeGenerator, api as default, encode, encodeChat, encodeChatGenerator, encodeGenerator, estimateCost, isWithinTokenLimit, setMergeCacheSize, vocabularySize };
11
11
  //# sourceMappingURL=o4-mini-deep-research.d.ts.map
@@ -5,7 +5,7 @@ import { EncodeOptions, GptEncoding } from "../GptEncoding.js";
5
5
  import { EndOfPrompt, EndOfText, FimMiddle, FimPrefix, FimSuffix, HarmonyCall, HarmonyChannel, HarmonyConstrain, HarmonyEnd, HarmonyMessage, HarmonyReturn, HarmonyStart, HarmonyStartOfText, ImEnd, ImSep, ImStart } from "../specialTokens.js";
6
6
  //#region src/model/o4-mini.d.ts
7
7
  declare const api: GptEncoding;
8
- declare const decode: (inputTokensToDecode: Iterable<number>) => string, decodeAsyncGenerator: (inputTokensToDecode: AsyncIterable<number>) => AsyncGenerator<string, void>, decodeGenerator: (inputTokensToDecode: Iterable<number>) => Generator<string, void, void>, encode: (lineToEncode: string, encodeOptions?: EncodeOptions) => number[], encodeGenerator: (lineToEncode: string, encodeOptions?: EncodeOptions) => Generator<number[], number, undefined>, isWithinTokenLimit: (input: string | Iterable<ChatMessage>, tokenLimit: number, encodeOptions?: EncodeOptions) => false | number, countTokens: (input: string | Iterable<ChatMessage>, encodeOptions?: EncodeOptions) => number, encodeChat: (chat: readonly ChatMessage[], model?: "gpt-3.5-0301" | "gpt-3.5" | "gpt-3.5-turbo-0613" | "gpt-4-1106-preview" | "gpt-4-32k" | "gpt-2" | "gpt2" | "text-ada-001" | "text-babbage-001" | "text-curie-001" | "text-davinci-001" | "text-davinci-002" | "text-davinci-003" | "ada" | "babbage" | "curie" | "davinci" | "code-davinci-001" | "code-davinci-002" | "davinci-codex" | "code-davinci-edit-001" | "code-cushman-001" | "code-cushman-002" | "cushman-codex" | "code-search-ada-code-001" | "code-search-ada-text-001" | "text-davinci-edit-001" | "text-similarity-ada-001" | "text-search-ada-doc-001" | "text-search-ada-query-001" | "text-similarity-babbage-001" | "text-search-babbage-doc-001" | "text-search-babbage-query-001" | "code-search-babbage-code-001" | "code-search-babbage-text-001" | "text-similarity-curie-001" | "text-search-curie-doc-001" | "text-search-curie-query-001" | "text-similarity-davinci-001" | "text-search-davinci-doc-001" | "text-search-davinci-query-001" | "babbage-002" | "chat-latest" | "chatgpt-4o-latest" | "chatgpt-image-latest" | "codex-mini-latest" | "computer-use-preview-2025-03-11" | "computer-use-preview" | "dall-e-2" | "dall-e-3" | "davinci-002" | "gpt-5.6-sol" | "daybreak-blue-latest" | "gpt-5.6-cyber" | "daybreak-red-latest" | "gpt-3.5-turbo-16k-0613" | "gpt-3.5-turbo-instruct" | "gpt-3.5-turbo-0125" | "gpt-3.5-turbo-1106" | "gpt-3.5-turbo" | "gpt-4-0125-preview" | "gpt-4-1106-vision-preview" | "gpt-4-turbo-preview" | "gpt-4-turbo-2024-04-09" | "gpt-4-turbo" | "gpt-4.1-mini-2025-04-14" | "gpt-4.1-mini" | "gpt-4.1-nano-2025-04-14" | "gpt-4.1-nano" | "gpt-4.1-2025-04-14" | "gpt-4.1" | "gpt-4.5-preview-2025-02-27" | "gpt-4.5-preview" | "gpt-4-0613" | "gpt-4-0314" | "gpt-4" | "gpt-4o-audio-preview-2025-06-03" | "gpt-4o-audio-preview-2024-12-17" | "gpt-4o-audio-preview-2024-10-01" | "gpt-4o-audio-preview" | "gpt-4o-mini-audio-preview-2024-12-17" | "gpt-4o-mini-audio-preview" | "gpt-4o-mini-realtime-preview-2024-12-17" | "gpt-4o-mini-realtime-preview" | "gpt-4o-mini-search-preview-2025-03-11" | "gpt-4o-mini-search-preview" | "gpt-4o-mini-transcribe-2025-03-20" | "gpt-4o-mini-transcribe-2025-12-15" | "gpt-4o-mini-transcribe" | "gpt-4o-mini-tts-2025-03-20" | "gpt-4o-mini-tts-2025-12-15" | "gpt-4o-mini-tts" | "gpt-4o-mini-2024-07-18" | "gpt-4o-mini" | "gpt-4o-realtime-preview-2025-06-03" | "gpt-4o-realtime-preview-2024-12-17" | "gpt-4o-realtime-preview-2024-10-01" | "gpt-4o-realtime-preview" | "gpt-4o-search-preview-2025-03-11" | "gpt-4o-search-preview" | "gpt-4o-transcribe-diarize" | "gpt-4o-transcribe" | "gpt-4o-2024-11-20" | "gpt-4o-2024-08-06" | "gpt-4o-2024-05-13" | "gpt-4o" | "gpt-5-chat-latest" | "gpt-5-codex" | "gpt-5-mini-2025-08-07" | "gpt-5-mini" | "gpt-5-nano-2025-08-07" | "gpt-5-nano" | "gpt-5-pro-2025-10-06" | "gpt-5-pro" | "gpt-5.1-chat-latest" | "gpt-5.1-codex-max" | "gpt-5.1-codex-mini" | "gpt-5.1-codex" | "gpt-5.1-2025-11-13" | "gpt-5.1" | "gpt-5.2-chat-latest" | "gpt-5.2-codex" | "gpt-5.2-pro-2025-12-11" | "gpt-5.2-pro" | "gpt-5.2-2025-12-11" | "gpt-5.2" | "gpt-5.3-chat-latest" | "gpt-5.3-codex" | "gpt-5.4-mini-2026-03-17" | "gpt-5.4-mini" | "gpt-5.4-nano-2026-03-17" | "gpt-5.4-nano" | "gpt-5.4-pro-2026-03-05" | "gpt-5.4-pro" | "gpt-5.4-2026-03-05" | "gpt-5.4" | "gpt-5.5-pro-2026-04-23" | "gpt-5.5-pro" | "gpt-5.5-2026-04-23" | "gpt-5.5" | "gpt-5.6-luna" | "gpt-5.6-terra" | "gpt-5-2025-08-07" | "gpt-5" | "gpt-audio-1.5" | "gpt-audio-mini-2025-10-06" | "gpt-audio-mini-2025-12-15" | "gpt-audio-mini" | "gpt-audio-2025-08-28" | "gpt-audio" | "gpt-image-1-mini" | "gpt-image-1.5-2025-12-16" | "gpt-image-1.5" | "gpt-image-1" | "gpt-image-2-2026-04-21" | "gpt-image-2" | "gpt-live-transcribe" | "gpt-oss-120b" | "gpt-oss-20b" | "gpt-realtime-1.5" | "gpt-realtime-2.1-mini" | "gpt-realtime-2.1" | "gpt-realtime-2" | "gpt-realtime-mini-2025-10-06" | "gpt-realtime-mini-2025-12-15" | "gpt-realtime-mini" | "gpt-realtime-translate" | "gpt-realtime-whisper" | "gpt-realtime-2025-08-28" | "gpt-realtime" | "gpt-transcribe" | "o1-mini-2024-09-12" | "o1-mini" | "o1-preview-2024-09-12" | "o1-preview" | "o1-pro-2025-03-19" | "o1-pro" | "o1-2024-12-17" | "o1" | "o3-deep-research-2025-06-26" | "o3-deep-research" | "o3-mini-2025-01-31" | "o3-mini" | "o3-pro-2025-06-10" | "o3-pro" | "o3-2025-04-16" | "o3" | "o4-mini-deep-research-2025-06-26" | "o4-mini-deep-research" | "o4-mini-2025-04-16" | "o4-mini" | "omni-moderation-2024-09-26" | "omni-moderation-latest" | "sora-2-pro-2025-10-06" | "sora-2-pro" | "sora-2-2025-12-08" | "sora-2-2025-10-06" | "sora-2" | "text-embedding-3-large" | "text-embedding-3-small" | "text-embedding-ada-002" | "text-moderation-007" | "text-moderation-latest" | "text-moderation-stable" | "tts-1-hd" | "tts-1" | "whisper-1" | undefined, encodeOptions?: EncodeOptions & EncodeChatOptions) => number[], countChatCompletionTokens: ((request: ChatCompletionRequest) => number) | undefined, encodeChatGenerator: (chat: Iterable<ChatMessage>, model?: "gpt-3.5-0301" | "gpt-3.5" | "gpt-3.5-turbo-0613" | "gpt-4-1106-preview" | "gpt-4-32k" | "gpt-2" | "gpt2" | "text-ada-001" | "text-babbage-001" | "text-curie-001" | "text-davinci-001" | "text-davinci-002" | "text-davinci-003" | "ada" | "babbage" | "curie" | "davinci" | "code-davinci-001" | "code-davinci-002" | "davinci-codex" | "code-davinci-edit-001" | "code-cushman-001" | "code-cushman-002" | "cushman-codex" | "code-search-ada-code-001" | "code-search-ada-text-001" | "text-davinci-edit-001" | "text-similarity-ada-001" | "text-search-ada-doc-001" | "text-search-ada-query-001" | "text-similarity-babbage-001" | "text-search-babbage-doc-001" | "text-search-babbage-query-001" | "code-search-babbage-code-001" | "code-search-babbage-text-001" | "text-similarity-curie-001" | "text-search-curie-doc-001" | "text-search-curie-query-001" | "text-similarity-davinci-001" | "text-search-davinci-doc-001" | "text-search-davinci-query-001" | "babbage-002" | "chat-latest" | "chatgpt-4o-latest" | "chatgpt-image-latest" | "codex-mini-latest" | "computer-use-preview-2025-03-11" | "computer-use-preview" | "dall-e-2" | "dall-e-3" | "davinci-002" | "gpt-5.6-sol" | "daybreak-blue-latest" | "gpt-5.6-cyber" | "daybreak-red-latest" | "gpt-3.5-turbo-16k-0613" | "gpt-3.5-turbo-instruct" | "gpt-3.5-turbo-0125" | "gpt-3.5-turbo-1106" | "gpt-3.5-turbo" | "gpt-4-0125-preview" | "gpt-4-1106-vision-preview" | "gpt-4-turbo-preview" | "gpt-4-turbo-2024-04-09" | "gpt-4-turbo" | "gpt-4.1-mini-2025-04-14" | "gpt-4.1-mini" | "gpt-4.1-nano-2025-04-14" | "gpt-4.1-nano" | "gpt-4.1-2025-04-14" | "gpt-4.1" | "gpt-4.5-preview-2025-02-27" | "gpt-4.5-preview" | "gpt-4-0613" | "gpt-4-0314" | "gpt-4" | "gpt-4o-audio-preview-2025-06-03" | "gpt-4o-audio-preview-2024-12-17" | "gpt-4o-audio-preview-2024-10-01" | "gpt-4o-audio-preview" | "gpt-4o-mini-audio-preview-2024-12-17" | "gpt-4o-mini-audio-preview" | "gpt-4o-mini-realtime-preview-2024-12-17" | "gpt-4o-mini-realtime-preview" | "gpt-4o-mini-search-preview-2025-03-11" | "gpt-4o-mini-search-preview" | "gpt-4o-mini-transcribe-2025-03-20" | "gpt-4o-mini-transcribe-2025-12-15" | "gpt-4o-mini-transcribe" | "gpt-4o-mini-tts-2025-03-20" | "gpt-4o-mini-tts-2025-12-15" | "gpt-4o-mini-tts" | "gpt-4o-mini-2024-07-18" | "gpt-4o-mini" | "gpt-4o-realtime-preview-2025-06-03" | "gpt-4o-realtime-preview-2024-12-17" | "gpt-4o-realtime-preview-2024-10-01" | "gpt-4o-realtime-preview" | "gpt-4o-search-preview-2025-03-11" | "gpt-4o-search-preview" | "gpt-4o-transcribe-diarize" | "gpt-4o-transcribe" | "gpt-4o-2024-11-20" | "gpt-4o-2024-08-06" | "gpt-4o-2024-05-13" | "gpt-4o" | "gpt-5-chat-latest" | "gpt-5-codex" | "gpt-5-mini-2025-08-07" | "gpt-5-mini" | "gpt-5-nano-2025-08-07" | "gpt-5-nano" | "gpt-5-pro-2025-10-06" | "gpt-5-pro" | "gpt-5.1-chat-latest" | "gpt-5.1-codex-max" | "gpt-5.1-codex-mini" | "gpt-5.1-codex" | "gpt-5.1-2025-11-13" | "gpt-5.1" | "gpt-5.2-chat-latest" | "gpt-5.2-codex" | "gpt-5.2-pro-2025-12-11" | "gpt-5.2-pro" | "gpt-5.2-2025-12-11" | "gpt-5.2" | "gpt-5.3-chat-latest" | "gpt-5.3-codex" | "gpt-5.4-mini-2026-03-17" | "gpt-5.4-mini" | "gpt-5.4-nano-2026-03-17" | "gpt-5.4-nano" | "gpt-5.4-pro-2026-03-05" | "gpt-5.4-pro" | "gpt-5.4-2026-03-05" | "gpt-5.4" | "gpt-5.5-pro-2026-04-23" | "gpt-5.5-pro" | "gpt-5.5-2026-04-23" | "gpt-5.5" | "gpt-5.6-luna" | "gpt-5.6-terra" | "gpt-5-2025-08-07" | "gpt-5" | "gpt-audio-1.5" | "gpt-audio-mini-2025-10-06" | "gpt-audio-mini-2025-12-15" | "gpt-audio-mini" | "gpt-audio-2025-08-28" | "gpt-audio" | "gpt-image-1-mini" | "gpt-image-1.5-2025-12-16" | "gpt-image-1.5" | "gpt-image-1" | "gpt-image-2-2026-04-21" | "gpt-image-2" | "gpt-live-transcribe" | "gpt-oss-120b" | "gpt-oss-20b" | "gpt-realtime-1.5" | "gpt-realtime-2.1-mini" | "gpt-realtime-2.1" | "gpt-realtime-2" | "gpt-realtime-mini-2025-10-06" | "gpt-realtime-mini-2025-12-15" | "gpt-realtime-mini" | "gpt-realtime-translate" | "gpt-realtime-whisper" | "gpt-realtime-2025-08-28" | "gpt-realtime" | "gpt-transcribe" | "o1-mini-2024-09-12" | "o1-mini" | "o1-preview-2024-09-12" | "o1-preview" | "o1-pro-2025-03-19" | "o1-pro" | "o1-2024-12-17" | "o1" | "o3-deep-research-2025-06-26" | "o3-deep-research" | "o3-mini-2025-01-31" | "o3-mini" | "o3-pro-2025-06-10" | "o3-pro" | "o3-2025-04-16" | "o3" | "o4-mini-deep-research-2025-06-26" | "o4-mini-deep-research" | "o4-mini-2025-04-16" | "o4-mini" | "omni-moderation-2024-09-26" | "omni-moderation-latest" | "sora-2-pro-2025-10-06" | "sora-2-pro" | "sora-2-2025-12-08" | "sora-2-2025-10-06" | "sora-2" | "text-embedding-3-large" | "text-embedding-3-small" | "text-embedding-ada-002" | "text-moderation-007" | "text-moderation-latest" | "text-moderation-stable" | "tts-1-hd" | "tts-1" | "whisper-1" | undefined, encodeOptions?: EncodeOptions & EncodeChatOptions) => Generator<number[], void, undefined>, vocabularySize: number, setMergeCacheSize: (size: number) => void, clearMergeCache: () => void, estimateCost: (tokenCount: number, modelSpec?: ModelSpec | undefined) => PriceData;
8
+ declare const decode: (inputTokensToDecode: Iterable<number>) => string, decodeAsyncGenerator: (inputTokensToDecode: AsyncIterable<number>) => AsyncGenerator<string, void>, decodeGenerator: (inputTokensToDecode: Iterable<number>) => Generator<string, void, void>, encode: (lineToEncode: string, encodeOptions?: EncodeOptions) => number[], encodeGenerator: (lineToEncode: string, encodeOptions?: EncodeOptions) => Generator<number[], number, undefined>, isWithinTokenLimit: (input: string | Iterable<ChatMessage>, tokenLimit: number, encodeOptions?: EncodeOptions) => false | number, countTokens: (input: string | Iterable<ChatMessage>, encodeOptions?: EncodeOptions) => number, encodeChat: (chat: readonly ChatMessage[], model?: "gpt2" | "gpt-3.5-0301" | "gpt-3.5" | "gpt-3.5-turbo-0613" | "gpt-4-1106-preview" | "gpt-4-32k" | "gpt-2" | "text-ada-001" | "text-babbage-001" | "text-curie-001" | "text-davinci-001" | "text-davinci-002" | "text-davinci-003" | "ada" | "babbage" | "curie" | "davinci" | "code-davinci-001" | "code-davinci-002" | "davinci-codex" | "code-davinci-edit-001" | "code-cushman-001" | "code-cushman-002" | "cushman-codex" | "code-search-ada-code-001" | "code-search-ada-text-001" | "text-davinci-edit-001" | "text-similarity-ada-001" | "text-search-ada-doc-001" | "text-search-ada-query-001" | "text-similarity-babbage-001" | "text-search-babbage-doc-001" | "text-search-babbage-query-001" | "code-search-babbage-code-001" | "code-search-babbage-text-001" | "text-similarity-curie-001" | "text-search-curie-doc-001" | "text-search-curie-query-001" | "text-similarity-davinci-001" | "text-search-davinci-doc-001" | "text-search-davinci-query-001" | "babbage-002" | "chat-latest" | "chatgpt-4o-latest" | "chatgpt-image-latest" | "codex-mini-latest" | "computer-use-preview-2025-03-11" | "computer-use-preview" | "dall-e-2" | "dall-e-3" | "davinci-002" | "gpt-5.6-sol" | "daybreak-blue-latest" | "gpt-5.6-cyber" | "daybreak-red-latest" | "gpt-3.5-turbo-16k-0613" | "gpt-3.5-turbo-instruct" | "gpt-3.5-turbo-0125" | "gpt-3.5-turbo-1106" | "gpt-3.5-turbo" | "gpt-4-0125-preview" | "gpt-4-1106-vision-preview" | "gpt-4-turbo-preview" | "gpt-4-turbo-2024-04-09" | "gpt-4-turbo" | "gpt-4.1-mini-2025-04-14" | "gpt-4.1-mini" | "gpt-4.1-nano-2025-04-14" | "gpt-4.1-nano" | "gpt-4.1-2025-04-14" | "gpt-4.1" | "gpt-4.5-preview-2025-02-27" | "gpt-4.5-preview" | "gpt-4-0613" | "gpt-4-0314" | "gpt-4" | "gpt-4o-audio-preview-2025-06-03" | "gpt-4o-audio-preview-2024-12-17" | "gpt-4o-audio-preview-2024-10-01" | "gpt-4o-audio-preview" | "gpt-4o-mini-audio-preview-2024-12-17" | "gpt-4o-mini-audio-preview" | "gpt-4o-mini-realtime-preview-2024-12-17" | "gpt-4o-mini-realtime-preview" | "gpt-4o-mini-search-preview-2025-03-11" | "gpt-4o-mini-search-preview" | "gpt-4o-mini-transcribe-2025-03-20" | "gpt-4o-mini-transcribe-2025-12-15" | "gpt-4o-mini-transcribe" | "gpt-4o-mini-tts-2025-03-20" | "gpt-4o-mini-tts-2025-12-15" | "gpt-4o-mini-tts" | "gpt-4o-mini-2024-07-18" | "gpt-4o-mini" | "gpt-4o-realtime-preview-2025-06-03" | "gpt-4o-realtime-preview-2024-12-17" | "gpt-4o-realtime-preview-2024-10-01" | "gpt-4o-realtime-preview" | "gpt-4o-search-preview-2025-03-11" | "gpt-4o-search-preview" | "gpt-4o-transcribe-diarize" | "gpt-4o-transcribe" | "gpt-4o-2024-11-20" | "gpt-4o-2024-08-06" | "gpt-4o-2024-05-13" | "gpt-4o" | "gpt-5-chat-latest" | "gpt-5-codex" | "gpt-5-mini-2025-08-07" | "gpt-5-mini" | "gpt-5-nano-2025-08-07" | "gpt-5-nano" | "gpt-5-pro-2025-10-06" | "gpt-5-pro" | "gpt-5.1-chat-latest" | "gpt-5.1-codex-max" | "gpt-5.1-codex-mini" | "gpt-5.1-codex" | "gpt-5.1-2025-11-13" | "gpt-5.1" | "gpt-5.2-chat-latest" | "gpt-5.2-codex" | "gpt-5.2-pro-2025-12-11" | "gpt-5.2-pro" | "gpt-5.2-2025-12-11" | "gpt-5.2" | "gpt-5.3-chat-latest" | "gpt-5.3-codex" | "gpt-5.4-mini-2026-03-17" | "gpt-5.4-mini" | "gpt-5.4-nano-2026-03-17" | "gpt-5.4-nano" | "gpt-5.4-pro-2026-03-05" | "gpt-5.4-pro" | "gpt-5.4-2026-03-05" | "gpt-5.4" | "gpt-5.5-pro-2026-04-23" | "gpt-5.5-pro" | "gpt-5.5-2026-04-23" | "gpt-5.5" | "gpt-5.6-luna" | "gpt-5.6-terra" | "gpt-5-2025-08-07" | "gpt-5" | "gpt-audio-1.5" | "gpt-audio-mini-2025-10-06" | "gpt-audio-mini-2025-12-15" | "gpt-audio-mini" | "gpt-audio-2025-08-28" | "gpt-audio" | "gpt-image-1-mini" | "gpt-image-1.5-2025-12-16" | "gpt-image-1.5" | "gpt-image-1" | "gpt-image-2-2026-04-21" | "gpt-image-2" | "gpt-live-transcribe" | "gpt-oss-120b" | "gpt-oss-20b" | "gpt-realtime-1.5" | "gpt-realtime-2.1-mini" | "gpt-realtime-2.1" | "gpt-realtime-2" | "gpt-realtime-mini-2025-10-06" | "gpt-realtime-mini-2025-12-15" | "gpt-realtime-mini" | "gpt-realtime-translate" | "gpt-realtime-whisper" | "gpt-realtime-2025-08-28" | "gpt-realtime" | "gpt-transcribe" | "o1-mini-2024-09-12" | "o1-mini" | "o1-preview-2024-09-12" | "o1-preview" | "o1-pro-2025-03-19" | "o1-pro" | "o1-2024-12-17" | "o1" | "o3-deep-research-2025-06-26" | "o3-deep-research" | "o3-mini-2025-01-31" | "o3-mini" | "o3-pro-2025-06-10" | "o3-pro" | "o3-2025-04-16" | "o3" | "o4-mini-deep-research-2025-06-26" | "o4-mini-deep-research" | "o4-mini-2025-04-16" | "o4-mini" | "omni-moderation-2024-09-26" | "omni-moderation-latest" | "sora-2-pro-2025-10-06" | "sora-2-pro" | "sora-2-2025-12-08" | "sora-2-2025-10-06" | "sora-2" | "text-embedding-3-large" | "text-embedding-3-small" | "text-embedding-ada-002" | "text-moderation-007" | "text-moderation-latest" | "text-moderation-stable" | "tts-1-hd" | "tts-1" | "whisper-1" | undefined, encodeOptions?: EncodeOptions & EncodeChatOptions) => number[], countChatCompletionTokens: ((request: ChatCompletionRequest) => number) | undefined, encodeChatGenerator: (chat: Iterable<ChatMessage>, model?: "gpt2" | "gpt-3.5-0301" | "gpt-3.5" | "gpt-3.5-turbo-0613" | "gpt-4-1106-preview" | "gpt-4-32k" | "gpt-2" | "text-ada-001" | "text-babbage-001" | "text-curie-001" | "text-davinci-001" | "text-davinci-002" | "text-davinci-003" | "ada" | "babbage" | "curie" | "davinci" | "code-davinci-001" | "code-davinci-002" | "davinci-codex" | "code-davinci-edit-001" | "code-cushman-001" | "code-cushman-002" | "cushman-codex" | "code-search-ada-code-001" | "code-search-ada-text-001" | "text-davinci-edit-001" | "text-similarity-ada-001" | "text-search-ada-doc-001" | "text-search-ada-query-001" | "text-similarity-babbage-001" | "text-search-babbage-doc-001" | "text-search-babbage-query-001" | "code-search-babbage-code-001" | "code-search-babbage-text-001" | "text-similarity-curie-001" | "text-search-curie-doc-001" | "text-search-curie-query-001" | "text-similarity-davinci-001" | "text-search-davinci-doc-001" | "text-search-davinci-query-001" | "babbage-002" | "chat-latest" | "chatgpt-4o-latest" | "chatgpt-image-latest" | "codex-mini-latest" | "computer-use-preview-2025-03-11" | "computer-use-preview" | "dall-e-2" | "dall-e-3" | "davinci-002" | "gpt-5.6-sol" | "daybreak-blue-latest" | "gpt-5.6-cyber" | "daybreak-red-latest" | "gpt-3.5-turbo-16k-0613" | "gpt-3.5-turbo-instruct" | "gpt-3.5-turbo-0125" | "gpt-3.5-turbo-1106" | "gpt-3.5-turbo" | "gpt-4-0125-preview" | "gpt-4-1106-vision-preview" | "gpt-4-turbo-preview" | "gpt-4-turbo-2024-04-09" | "gpt-4-turbo" | "gpt-4.1-mini-2025-04-14" | "gpt-4.1-mini" | "gpt-4.1-nano-2025-04-14" | "gpt-4.1-nano" | "gpt-4.1-2025-04-14" | "gpt-4.1" | "gpt-4.5-preview-2025-02-27" | "gpt-4.5-preview" | "gpt-4-0613" | "gpt-4-0314" | "gpt-4" | "gpt-4o-audio-preview-2025-06-03" | "gpt-4o-audio-preview-2024-12-17" | "gpt-4o-audio-preview-2024-10-01" | "gpt-4o-audio-preview" | "gpt-4o-mini-audio-preview-2024-12-17" | "gpt-4o-mini-audio-preview" | "gpt-4o-mini-realtime-preview-2024-12-17" | "gpt-4o-mini-realtime-preview" | "gpt-4o-mini-search-preview-2025-03-11" | "gpt-4o-mini-search-preview" | "gpt-4o-mini-transcribe-2025-03-20" | "gpt-4o-mini-transcribe-2025-12-15" | "gpt-4o-mini-transcribe" | "gpt-4o-mini-tts-2025-03-20" | "gpt-4o-mini-tts-2025-12-15" | "gpt-4o-mini-tts" | "gpt-4o-mini-2024-07-18" | "gpt-4o-mini" | "gpt-4o-realtime-preview-2025-06-03" | "gpt-4o-realtime-preview-2024-12-17" | "gpt-4o-realtime-preview-2024-10-01" | "gpt-4o-realtime-preview" | "gpt-4o-search-preview-2025-03-11" | "gpt-4o-search-preview" | "gpt-4o-transcribe-diarize" | "gpt-4o-transcribe" | "gpt-4o-2024-11-20" | "gpt-4o-2024-08-06" | "gpt-4o-2024-05-13" | "gpt-4o" | "gpt-5-chat-latest" | "gpt-5-codex" | "gpt-5-mini-2025-08-07" | "gpt-5-mini" | "gpt-5-nano-2025-08-07" | "gpt-5-nano" | "gpt-5-pro-2025-10-06" | "gpt-5-pro" | "gpt-5.1-chat-latest" | "gpt-5.1-codex-max" | "gpt-5.1-codex-mini" | "gpt-5.1-codex" | "gpt-5.1-2025-11-13" | "gpt-5.1" | "gpt-5.2-chat-latest" | "gpt-5.2-codex" | "gpt-5.2-pro-2025-12-11" | "gpt-5.2-pro" | "gpt-5.2-2025-12-11" | "gpt-5.2" | "gpt-5.3-chat-latest" | "gpt-5.3-codex" | "gpt-5.4-mini-2026-03-17" | "gpt-5.4-mini" | "gpt-5.4-nano-2026-03-17" | "gpt-5.4-nano" | "gpt-5.4-pro-2026-03-05" | "gpt-5.4-pro" | "gpt-5.4-2026-03-05" | "gpt-5.4" | "gpt-5.5-pro-2026-04-23" | "gpt-5.5-pro" | "gpt-5.5-2026-04-23" | "gpt-5.5" | "gpt-5.6-luna" | "gpt-5.6-terra" | "gpt-5-2025-08-07" | "gpt-5" | "gpt-audio-1.5" | "gpt-audio-mini-2025-10-06" | "gpt-audio-mini-2025-12-15" | "gpt-audio-mini" | "gpt-audio-2025-08-28" | "gpt-audio" | "gpt-image-1-mini" | "gpt-image-1.5-2025-12-16" | "gpt-image-1.5" | "gpt-image-1" | "gpt-image-2-2026-04-21" | "gpt-image-2" | "gpt-live-transcribe" | "gpt-oss-120b" | "gpt-oss-20b" | "gpt-realtime-1.5" | "gpt-realtime-2.1-mini" | "gpt-realtime-2.1" | "gpt-realtime-2" | "gpt-realtime-mini-2025-10-06" | "gpt-realtime-mini-2025-12-15" | "gpt-realtime-mini" | "gpt-realtime-translate" | "gpt-realtime-whisper" | "gpt-realtime-2025-08-28" | "gpt-realtime" | "gpt-transcribe" | "o1-mini-2024-09-12" | "o1-mini" | "o1-preview-2024-09-12" | "o1-preview" | "o1-pro-2025-03-19" | "o1-pro" | "o1-2024-12-17" | "o1" | "o3-deep-research-2025-06-26" | "o3-deep-research" | "o3-mini-2025-01-31" | "o3-mini" | "o3-pro-2025-06-10" | "o3-pro" | "o3-2025-04-16" | "o3" | "o4-mini-deep-research-2025-06-26" | "o4-mini-deep-research" | "o4-mini-2025-04-16" | "o4-mini" | "omni-moderation-2024-09-26" | "omni-moderation-latest" | "sora-2-pro-2025-10-06" | "sora-2-pro" | "sora-2-2025-12-08" | "sora-2-2025-10-06" | "sora-2" | "text-embedding-3-large" | "text-embedding-3-small" | "text-embedding-ada-002" | "text-moderation-007" | "text-moderation-latest" | "text-moderation-stable" | "tts-1-hd" | "tts-1" | "whisper-1" | undefined, encodeOptions?: EncodeOptions & EncodeChatOptions) => Generator<number[], void, undefined>, vocabularySize: number, setMergeCacheSize: (size: number) => void, clearMergeCache: () => void, estimateCost: (tokenCount: number, modelSpec?: ModelSpec | undefined) => PriceData;
9
9
  //#endregion
10
10
  export { ALL_SPECIAL_TOKENS, DEFAULT_MERGE_CACHE_SIZE, EndOfPrompt, EndOfText, FimMiddle, FimPrefix, FimSuffix, HarmonyCall, HarmonyChannel, HarmonyConstrain, HarmonyEnd, HarmonyMessage, HarmonyReturn, HarmonyStart, HarmonyStartOfText, ImEnd, ImSep, ImStart, clearMergeCache, countChatCompletionTokens, countTokens, decode, decodeAsyncGenerator, decodeGenerator, api as default, encode, encodeChat, encodeChatGenerator, encodeGenerator, estimateCost, isWithinTokenLimit, setMergeCacheSize, vocabularySize };
11
11
  //# sourceMappingURL=o4-mini.d.ts.map
package/esm/utfUtil.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  //#region src/utfUtil.d.ts
2
2
  declare const isAscii: (codePoint: number) => boolean;
3
3
  declare function endsWithIncompleteUtfPairSurrogate(string: string): boolean;
4
+ declare function startsWithByteOrderMark(bytes: Uint8Array): boolean;
4
5
  declare function tryConvertToString(arr: Uint8Array): string | undefined;
5
6
  declare function compareUint8Arrays(a: Uint8Array, b: Uint8Array): number;
6
7
  //#endregion
7
- export { compareUint8Arrays, endsWithIncompleteUtfPairSurrogate, isAscii, tryConvertToString };
8
+ export { compareUint8Arrays, endsWithIncompleteUtfPairSurrogate, isAscii, startsWithByteOrderMark, tryConvertToString };
8
9
  //# sourceMappingURL=utfUtil.d.ts.map
package/esm/utfUtil.js CHANGED
@@ -43,7 +43,13 @@ function isValidUTF8(bytes) {
43
43
  }
44
44
  return true;
45
45
  }
46
- const textDecoder = new TextDecoder("utf8", { fatal: false });
46
+ function startsWithByteOrderMark(bytes) {
47
+ return bytes.length >= 3 && bytes[0] === 239 && bytes[1] === 187 && bytes[2] === 191;
48
+ }
49
+ const textDecoder = new TextDecoder("utf8", {
50
+ fatal: false,
51
+ ignoreBOM: true
52
+ });
47
53
  function tryConvertToString(arr) {
48
54
  if (!isValidUTF8(arr)) return;
49
55
  return textDecoder.decode(arr);
@@ -54,6 +60,6 @@ function compareUint8Arrays(a, b) {
54
60
  return a.length - b.length;
55
61
  }
56
62
  //#endregion
57
- export { compareUint8Arrays, endsWithIncompleteUtfPairSurrogate, isAscii, tryConvertToString };
63
+ export { compareUint8Arrays, endsWithIncompleteUtfPairSurrogate, isAscii, startsWithByteOrderMark, tryConvertToString };
58
64
 
59
65
  //# sourceMappingURL=utfUtil.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utfUtil.js","names":[],"sources":["../src/utfUtil.ts"],"sourcesContent":["export const isAscii = (codePoint: number) => codePoint <= 0x7f\n\nconst HIGH_SURROGATE_START = 55_296\nconst HIGH_SURROGATE_END = 56_319\n\nexport function endsWithIncompleteUtfPairSurrogate(string: string): boolean {\n if (string.length === 0) return false\n // Check if the last character is a high surrogate\n const lastCharCode = string.charCodeAt(string.length - 1)\n return (\n lastCharCode >= HIGH_SURROGATE_START && lastCharCode <= HIGH_SURROGATE_END\n )\n}\n\nfunction isValidUTF8(bytes: Uint8Array): boolean {\n let i = 0\n while (i < bytes.length) {\n const byte1 = bytes[i]!\n\n let numBytes = 0\n let codePoint = 0\n\n // Determine the number of bytes in the current UTF-8 character\n if (byte1 <= 0x7f) {\n // 1-byte character (ASCII)\n numBytes = 1\n codePoint = byte1\n } else if ((byte1 & 0xe0) === 0xc0) {\n // 2-byte character\n numBytes = 2\n codePoint = byte1 & 0x1f\n if (byte1 <= 0xc1) return false // Overlong encoding not allowed\n } else if ((byte1 & 0xf0) === 0xe0) {\n // 3-byte character\n numBytes = 3\n codePoint = byte1 & 0x0f\n } else if ((byte1 & 0xf8) === 0xf0) {\n // 4-byte character\n numBytes = 4\n codePoint = byte1 & 0x07\n if (byte1 > 0xf4) return false // Code points above U+10FFFF not allowed\n } else {\n // Invalid first byte of UTF-8 character\n return false\n }\n\n // Ensure there are enough continuation bytes\n if (i + numBytes > bytes.length) return false\n\n // Process the continuation bytes\n for (let j = 1; j < numBytes; j++) {\n const byte = bytes[i + j]\n if (byte === undefined || (byte & 0xc0) !== 0x80) return false // Continuation bytes must start with '10'\n codePoint = (codePoint << 6) | (byte & 0x3f)\n }\n\n // Check for overlong encodings\n if (numBytes === 2 && codePoint < 0x80) return false // Overlong 2-byte sequence\n if (numBytes === 3 && codePoint < 2_048) return false // Overlong 3-byte sequence\n if (numBytes === 4 && codePoint < 65_536) return false // Overlong 4-byte sequence\n\n // Check for surrogate halves (U+D800 to U+DFFF)\n if (codePoint >= 55_296 && codePoint <= 57_343) return false\n\n // Check for code points above U+10FFFF\n if (codePoint > 1_114_111) return false\n\n // Move to the next character\n i += numBytes\n }\n return true\n}\n\nconst textDecoder = new TextDecoder('utf8', { fatal: false })\n\nexport function tryConvertToString(arr: Uint8Array): string | undefined {\n if (!isValidUTF8(arr)) {\n return undefined\n }\n return textDecoder.decode(arr)\n}\n\n// Helper function to compare two Uint8Arrays lexicographically\nexport function compareUint8Arrays(a: Uint8Array, b: Uint8Array): number {\n const len = Math.min(a.length, b.length)\n for (let i = 0; i < len; i++) {\n if (a[i] !== b[i]) {\n return a[i]! - b[i]!\n }\n }\n return a.length - b.length\n}\n"],"mappings":";AAAA,MAAa,WAAW,cAAsB,aAAa;AAE3D,MAAM,uBAAuB;AAC7B,MAAM,qBAAqB;AAE3B,SAAgB,mCAAmC,QAAyB;CAC1E,IAAI,OAAO,WAAW,GAAG,OAAO;CAEhC,MAAM,eAAe,OAAO,WAAW,OAAO,SAAS,CAAC;CACxD,OACE,gBAAgB,wBAAwB,gBAAgB;AAE5D;AAEA,SAAS,YAAY,OAA4B;CAC/C,IAAI,IAAI;CACR,OAAO,IAAI,MAAM,QAAQ;EACvB,MAAM,QAAQ,MAAM;EAEpB,IAAI,WAAW;EACf,IAAI,YAAY;EAGhB,IAAI,SAAS,KAAM;GAEjB,WAAW;GACX,YAAY;EACd,OAAO,KAAK,QAAQ,SAAU,KAAM;GAElC,WAAW;GACX,YAAY,QAAQ;GACpB,IAAI,SAAS,KAAM,OAAO;EAC5B,OAAO,KAAK,QAAQ,SAAU,KAAM;GAElC,WAAW;GACX,YAAY,QAAQ;EACtB,OAAO,KAAK,QAAQ,SAAU,KAAM;GAElC,WAAW;GACX,YAAY,QAAQ;GACpB,IAAI,QAAQ,KAAM,OAAO;EAC3B,OAEE,OAAO;EAIT,IAAI,IAAI,WAAW,MAAM,QAAQ,OAAO;EAGxC,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,KAAK;GACjC,MAAM,OAAO,MAAM,IAAI;GACvB,IAAI,SAAS,KAAA,MAAc,OAAO,SAAU,KAAM,OAAO;GACzD,YAAa,aAAa,IAAM,OAAO;EACzC;EAGA,IAAI,aAAa,KAAK,YAAY,KAAM,OAAO;EAC/C,IAAI,aAAa,KAAK,YAAY,MAAO,OAAO;EAChD,IAAI,aAAa,KAAK,YAAY,OAAQ,OAAO;EAGjD,IAAI,aAAa,SAAU,aAAa,OAAQ,OAAO;EAGvD,IAAI,YAAY,SAAW,OAAO;EAGlC,KAAK;CACP;CACA,OAAO;AACT;AAEA,MAAM,cAAc,IAAI,YAAY,QAAQ,EAAE,OAAO,MAAM,CAAC;AAE5D,SAAgB,mBAAmB,KAAqC;CACtE,IAAI,CAAC,YAAY,GAAG,GAClB;CAEF,OAAO,YAAY,OAAO,GAAG;AAC/B;AAGA,SAAgB,mBAAmB,GAAe,GAAuB;CACvE,MAAM,MAAM,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;CACvC,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KACvB,IAAI,EAAE,OAAO,EAAE,IACb,OAAO,EAAE,KAAM,EAAE;CAGrB,OAAO,EAAE,SAAS,EAAE;AACtB"}
1
+ {"version":3,"file":"utfUtil.js","names":[],"sources":["../src/utfUtil.ts"],"sourcesContent":["export const isAscii = (codePoint: number) => codePoint <= 0x7f\n\nconst HIGH_SURROGATE_START = 55_296\nconst HIGH_SURROGATE_END = 56_319\n\nexport function endsWithIncompleteUtfPairSurrogate(string: string): boolean {\n if (string.length === 0) return false\n // Check if the last character is a high surrogate\n const lastCharCode = string.charCodeAt(string.length - 1)\n return (\n lastCharCode >= HIGH_SURROGATE_START && lastCharCode <= HIGH_SURROGATE_END\n )\n}\n\nfunction isValidUTF8(bytes: Uint8Array): boolean {\n let i = 0\n while (i < bytes.length) {\n const byte1 = bytes[i]!\n\n let numBytes = 0\n let codePoint = 0\n\n // Determine the number of bytes in the current UTF-8 character\n if (byte1 <= 0x7f) {\n // 1-byte character (ASCII)\n numBytes = 1\n codePoint = byte1\n } else if ((byte1 & 0xe0) === 0xc0) {\n // 2-byte character\n numBytes = 2\n codePoint = byte1 & 0x1f\n if (byte1 <= 0xc1) return false // Overlong encoding not allowed\n } else if ((byte1 & 0xf0) === 0xe0) {\n // 3-byte character\n numBytes = 3\n codePoint = byte1 & 0x0f\n } else if ((byte1 & 0xf8) === 0xf0) {\n // 4-byte character\n numBytes = 4\n codePoint = byte1 & 0x07\n if (byte1 > 0xf4) return false // Code points above U+10FFFF not allowed\n } else {\n // Invalid first byte of UTF-8 character\n return false\n }\n\n // Ensure there are enough continuation bytes\n if (i + numBytes > bytes.length) return false\n\n // Process the continuation bytes\n for (let j = 1; j < numBytes; j++) {\n const byte = bytes[i + j]\n if (byte === undefined || (byte & 0xc0) !== 0x80) return false // Continuation bytes must start with '10'\n codePoint = (codePoint << 6) | (byte & 0x3f)\n }\n\n // Check for overlong encodings\n if (numBytes === 2 && codePoint < 0x80) return false // Overlong 2-byte sequence\n if (numBytes === 3 && codePoint < 2_048) return false // Overlong 3-byte sequence\n if (numBytes === 4 && codePoint < 65_536) return false // Overlong 4-byte sequence\n\n // Check for surrogate halves (U+D800 to U+DFFF)\n if (codePoint >= 55_296 && codePoint <= 57_343) return false\n\n // Check for code points above U+10FFFF\n if (codePoint > 1_114_111) return false\n\n // Move to the next character\n i += numBytes\n }\n return true\n}\n\nexport function startsWithByteOrderMark(bytes: Uint8Array): boolean {\n return (\n bytes.length >= 3 &&\n bytes[0] === 0xef &&\n bytes[1] === 0xbb &&\n bytes[2] === 0xbf\n )\n}\n\n// `ignoreBOM: true` keeps a leading U+FEFF in the output instead of silently\n// stripping it, so the bytes EF BB BF map to U+FEFF rather than to an empty string.\nconst textDecoder = new TextDecoder('utf8', { fatal: false, ignoreBOM: true })\n\nexport function tryConvertToString(arr: Uint8Array): string | undefined {\n if (!isValidUTF8(arr)) {\n return undefined\n }\n return textDecoder.decode(arr)\n}\n\n// Helper function to compare two Uint8Arrays lexicographically\nexport function compareUint8Arrays(a: Uint8Array, b: Uint8Array): number {\n const len = Math.min(a.length, b.length)\n for (let i = 0; i < len; i++) {\n if (a[i] !== b[i]) {\n return a[i]! - b[i]!\n }\n }\n return a.length - b.length\n}\n"],"mappings":";AAAA,MAAa,WAAW,cAAsB,aAAa;AAE3D,MAAM,uBAAuB;AAC7B,MAAM,qBAAqB;AAE3B,SAAgB,mCAAmC,QAAyB;CAC1E,IAAI,OAAO,WAAW,GAAG,OAAO;CAEhC,MAAM,eAAe,OAAO,WAAW,OAAO,SAAS,CAAC;CACxD,OACE,gBAAgB,wBAAwB,gBAAgB;AAE5D;AAEA,SAAS,YAAY,OAA4B;CAC/C,IAAI,IAAI;CACR,OAAO,IAAI,MAAM,QAAQ;EACvB,MAAM,QAAQ,MAAM;EAEpB,IAAI,WAAW;EACf,IAAI,YAAY;EAGhB,IAAI,SAAS,KAAM;GAEjB,WAAW;GACX,YAAY;EACd,OAAO,KAAK,QAAQ,SAAU,KAAM;GAElC,WAAW;GACX,YAAY,QAAQ;GACpB,IAAI,SAAS,KAAM,OAAO;EAC5B,OAAO,KAAK,QAAQ,SAAU,KAAM;GAElC,WAAW;GACX,YAAY,QAAQ;EACtB,OAAO,KAAK,QAAQ,SAAU,KAAM;GAElC,WAAW;GACX,YAAY,QAAQ;GACpB,IAAI,QAAQ,KAAM,OAAO;EAC3B,OAEE,OAAO;EAIT,IAAI,IAAI,WAAW,MAAM,QAAQ,OAAO;EAGxC,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,KAAK;GACjC,MAAM,OAAO,MAAM,IAAI;GACvB,IAAI,SAAS,KAAA,MAAc,OAAO,SAAU,KAAM,OAAO;GACzD,YAAa,aAAa,IAAM,OAAO;EACzC;EAGA,IAAI,aAAa,KAAK,YAAY,KAAM,OAAO;EAC/C,IAAI,aAAa,KAAK,YAAY,MAAO,OAAO;EAChD,IAAI,aAAa,KAAK,YAAY,OAAQ,OAAO;EAGjD,IAAI,aAAa,SAAU,aAAa,OAAQ,OAAO;EAGvD,IAAI,YAAY,SAAW,OAAO;EAGlC,KAAK;CACP;CACA,OAAO;AACT;AAEA,SAAgB,wBAAwB,OAA4B;CAClE,OACE,MAAM,UAAU,KAChB,MAAM,OAAO,OACb,MAAM,OAAO,OACb,MAAM,OAAO;AAEjB;AAIA,MAAM,cAAc,IAAI,YAAY,QAAQ;CAAE,OAAO;CAAO,WAAW;AAAK,CAAC;AAE7E,SAAgB,mBAAmB,KAAqC;CACtE,IAAI,CAAC,YAAY,GAAG,GAClB;CAEF,OAAO,YAAY,OAAO,GAAG;AAC/B;AAGA,SAAgB,mBAAmB,GAAe,GAAuB;CACvE,MAAM,MAAM,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;CACvC,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KACvB,IAAI,EAAE,OAAO,EAAE,IACb,OAAO,EAAE,KAAM,EAAE;CAGrB,OAAO,EAAE,SAAS,EAAE;AACtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gpt-tokenizer",
3
- "version": "4.0.1",
3
+ "version": "4.0.2",
4
4
  "description": "A pure JavaScript BPE tokenizer with model metadata and pricing for GPT-5, GPT-4o, o-series, and other OpenAI models",
5
5
  "keywords": [
6
6
  "BPE",
@@ -1,5 +1,10 @@
1
1
  import { DEFAULT_MERGE_CACHE_SIZE } from './constants.js'
2
- import { compareUint8Arrays, isAscii, tryConvertToString } from './utfUtil.js'
2
+ import {
3
+ compareUint8Arrays,
4
+ isAscii,
5
+ startsWithByteOrderMark,
6
+ tryConvertToString,
7
+ } from './utfUtil.js'
3
8
  import { escapeRegExp } from './util.js'
4
9
 
5
10
  export type RawBytePairRanks = readonly (string | readonly number[])[]
@@ -19,7 +24,8 @@ export interface BytePairEncodingConfig {
19
24
 
20
25
  const emptyBuffer = new Uint8Array(0)
21
26
 
22
- export const decoder = new TextDecoder('utf8')
27
+ // `ignoreBOM: true` keeps a leading U+FEFF in the decoded output.
28
+ export const decoder = new TextDecoder('utf8', { ignoreBOM: true })
23
29
 
24
30
  export class BytePairEncodingCore {
25
31
  readonly mergeableBytePairRankCount: number
@@ -70,6 +76,16 @@ export class BytePairEncodingCore {
70
76
  const byteArray = new Uint8Array(value)
71
77
  binaryLookup.push([byteArray, rank])
72
78
  this.bytePairNonUtfRankDecoder.set(rank, byteArray)
79
+ if (startsWithByteOrderMark(byteArray)) {
80
+ // The rank tables keep tokens that start with a UTF-8 byte order mark
81
+ // (EF BB BF) as raw bytes, because a plain decode would strip the mark.
82
+ // They are still valid UTF-8, so they must also be reachable through
83
+ // the string lookup that getBpeRankFromBytes uses for valid UTF-8.
84
+ const asString = tryConvertToString(byteArray)
85
+ if (asString !== undefined) {
86
+ this.bytePairStringRankEncoder.set(asString, rank)
87
+ }
88
+ }
73
89
  })
74
90
  this.bytePairNonUtfSortedEncoder = binaryLookup.sort((a, b) =>
75
91
  compareUint8Arrays(a[0], b[0]),
@@ -1,18 +1,22 @@
1
+ // The split patterns below use `\p{White_Space}` / `\P{White_Space}` where
2
+ // tiktoken's patterns use `\s` / `\S`: the regex engine behind tiktoken treats
3
+ // `\s` as the Unicode White_Space property, whereas JavaScript's `\s` differs
4
+ // from it on exactly two code points (U+0085 and U+FEFF).
1
5
  export const R50K_TOKEN_SPLIT_REGEX =
2
- /'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+/gu
6
+ /'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\p{White_Space}\p{L}\p{N}]+|\p{White_Space}+(?!\P{White_Space})|\p{White_Space}+/gu
3
7
 
4
8
  const CONTRACTION_SUFFIX_PATTERN = String.raw`'(?:[sS]|[dD]|[mM]|[tT]|[lL][lL]|[vV][eE]|[rR][eE])`
5
9
 
6
10
  const OPTIONAL_CONTRACTION_SUFFIX = String.raw`(?:${CONTRACTION_SUFFIX_PATTERN})?`
7
11
 
8
- const CL100K_TOKEN_SPLIT_PATTERN = String.raw`${CONTRACTION_SUFFIX_PATTERN}|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n]*|\s+$|\s*[\r\n]|\s+(?!\S)|\s`
12
+ const CL100K_TOKEN_SPLIT_PATTERN = String.raw`${CONTRACTION_SUFFIX_PATTERN}|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}{1,3}| ?[^\p{White_Space}\p{L}\p{N}]+[\r\n]*|\p{White_Space}+$|\p{White_Space}*[\r\n]|\p{White_Space}+(?!\P{White_Space})|\p{White_Space}`
9
13
 
10
14
  export const CL100K_TOKEN_SPLIT_REGEX = new RegExp(
11
15
  CL100K_TOKEN_SPLIT_PATTERN,
12
16
  'gu',
13
17
  )
14
18
 
15
- const O200K_TOKEN_SPLIT_PATTERN = String.raw`[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]*[\p{Ll}\p{Lm}\p{Lo}\p{M}]+${OPTIONAL_CONTRACTION_SUFFIX}|[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]+[\p{Ll}\p{Lm}\p{Lo}\p{M}]*${OPTIONAL_CONTRACTION_SUFFIX}|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n/]*|\s*[\r\n]+|\s+(?!\S)|\s+`
19
+ const O200K_TOKEN_SPLIT_PATTERN = String.raw`[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]*[\p{Ll}\p{Lm}\p{Lo}\p{M}]+${OPTIONAL_CONTRACTION_SUFFIX}|[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]+[\p{Ll}\p{Lm}\p{Lo}\p{M}]*${OPTIONAL_CONTRACTION_SUFFIX}|\p{N}{1,3}| ?[^\p{White_Space}\p{L}\p{N}]+[\r\n/]*|\p{White_Space}*[\r\n]+|\p{White_Space}+(?!\P{White_Space})|\p{White_Space}+`
16
20
 
17
21
  export const O200K_TOKEN_SPLIT_REGEX = new RegExp(
18
22
  O200K_TOKEN_SPLIT_PATTERN,
@@ -0,0 +1,247 @@
1
+ import { describe, expect, test } from 'vite-plus/test'
2
+ import { GptEncoding } from './GptEncoding.js'
3
+ import { type EncodingName } from './mapping.js'
4
+ import { resolveEncoding } from './resolveEncoding.js'
5
+
6
+ const getEncoding = (encodingName: string) =>
7
+ GptEncoding.getEncodingApi(encodingName as EncodingName, resolveEncoding)
8
+
9
+ /**
10
+ * Two things have to line up with tiktoken for these strings:
11
+ *
12
+ * - the split patterns must treat `\s` as the Unicode White_Space property.
13
+ * JavaScript's own `\s` differs from it on exactly two code points: U+0085
14
+ * (White_Space only) and U+FEFF (JavaScript `\s` only);
15
+ * - tokens that start with the UTF-8 byte order mark (EF BB BF, i.e. U+FEFF)
16
+ * must stay reachable, even though a plain `TextDecoder` strips that mark.
17
+ *
18
+ * Reference vectors generated with the Python `tiktoken` package
19
+ * (`encoding.encode(text)`).
20
+ */
21
+ const unicodeWhiteSpaceCases: [
22
+ encodingName: string,
23
+ text: string,
24
+ expected: number[],
25
+ ][] = [
26
+ ['cl100k_base', 'a\ufeffb', [64, 3305, 65]],
27
+ ['cl100k_base', 'Hello\ufeff\n', [9906, 62619]],
28
+ ['o200k_base', 'x\ufeff\ufeffy', [87, 135153, 88]],
29
+ ['o200k_base', 'a \u0085b', [64, 220, 126, 227, 65]],
30
+ ['cl100k_base', 'a \u0085b', [64, 220, 126, 227, 65]],
31
+ ['p50k_base', 'a \ufeffb', [64, 27332, 119, 123, 65]],
32
+ ['r50k_base', 'a \ufeffb', [64, 27332, 119, 123, 65]],
33
+ ['r50k_base', 'a \u0085b', [64, 220, 126, 227, 65]],
34
+ ['p50k_base', 'a \u0085b', [64, 220, 126, 227, 65]],
35
+ ['o200k_base', 'a\ufeffb', [64, 5574, 65]],
36
+ ['cl100k_base', 'x\ufeff\ufeffy', [87, 3305, 3305, 88]],
37
+ ['o200k_base', 'Hello\ufeff\n', [13225, 61992]],
38
+ ['o200k_base', '\ufeffHello world', [5574, 13225, 2375]],
39
+ ['cl100k_base', '\ufeffHello world', [3305, 9906, 1917]],
40
+ ['o200k_base', 'a\u0085b', [64, 126, 227, 65]],
41
+ ['cl100k_base', 'a\u0085\n\u0085b', [64, 126, 227, 198, 126, 227, 65]],
42
+ ['o200k_base', 'line one\u0085line two', [1137, 1001, 126, 227, 1137, 1920]],
43
+ ['cl100k_base', 'line one\u0085line two', [1074, 832, 126, 227, 1074, 1403]],
44
+ ['p50k_base', 'a\ufeffb', [64, 171, 119, 123, 65]],
45
+ ['r50k_base', 'a\ufeffb', [64, 171, 119, 123, 65]],
46
+ ]
47
+
48
+ /**
49
+ * Ordinary whitespace must keep tokenizing exactly as before (and exactly like
50
+ * tiktoken): the change above only affects U+0085 and U+FEFF.
51
+ */
52
+ const ordinaryWhiteSpaceCases: [
53
+ encodingName: string,
54
+ label: string,
55
+ text: string,
56
+ expected: number[],
57
+ ][] = [
58
+ ['cl100k_base', 'space', 'a b', [64, 220, 293]],
59
+ ['cl100k_base', 'tabs', 'a\t\tb\tc', [64, 197, 2282, 1470]],
60
+ ['cl100k_base', 'newlines', 'a\n\nb\r\nc\n', [64, 271, 65, 319, 66, 198]],
61
+ ['cl100k_base', 'nbsp', 'a\u00a0b \u00a0c', [64, 4194, 65, 220, 4194, 66]],
62
+ [
63
+ 'cl100k_base',
64
+ 'ideographic space',
65
+ 'a\u3000b\u3000\u3000c',
66
+ [64, 23249, 65, 23249, 23249, 66],
67
+ ],
68
+ [
69
+ 'cl100k_base',
70
+ 'line and paragraph separators',
71
+ 'a\u2028b\u2029c \u2028',
72
+ [64, 378, 101, 65, 378, 102, 66, 639, 101],
73
+ ],
74
+ [
75
+ 'cl100k_base',
76
+ 'mixed unicode spaces',
77
+ 'x\u2003y\u2009\u200az\u202f\u205f',
78
+ [87, 378, 225, 88, 378, 231, 378, 232, 89, 378, 107, 53233, 253],
79
+ ],
80
+ [
81
+ 'cl100k_base',
82
+ 'vertical tab and form feed',
83
+ 'a\u000bb\fc',
84
+ [64, 199, 65, 200, 66],
85
+ ],
86
+ ['cl100k_base', 'trailing whitespace', 'hello \n ', [15339, 5996, 256]],
87
+ ['cl100k_base', 'leading whitespace', ' hello', [256, 24748]],
88
+ ['o200k_base', 'space', 'a b', [64, 220, 287]],
89
+ ['o200k_base', 'tabs', 'a\t\tb\tc', [64, 197, 3722, 2736]],
90
+ ['o200k_base', 'newlines', 'a\n\nb\r\nc\n', [64, 279, 65, 370, 66, 198]],
91
+ ['o200k_base', 'nbsp', 'a\u00a0b \u00a0c', [64, 5310, 65, 220, 5310, 66]],
92
+ [
93
+ 'o200k_base',
94
+ 'ideographic space',
95
+ 'a\u3000b\u3000\u3000c',
96
+ [64, 1397, 65, 1397, 1397, 66],
97
+ ],
98
+ [
99
+ 'o200k_base',
100
+ 'line and paragraph separators',
101
+ 'a\u2028b\u2029c \u2028',
102
+ [64, 51008, 65, 318, 102, 66, 121514],
103
+ ],
104
+ [
105
+ 'o200k_base',
106
+ 'mixed unicode spaces',
107
+ 'x\u2003y\u2009\u200az\u202f\u205f',
108
+ [87, 33203, 88, 29106, 86741, 89, 35971, 37127, 253],
109
+ ],
110
+ [
111
+ 'o200k_base',
112
+ 'vertical tab and form feed',
113
+ 'a\u000bb\fc',
114
+ [64, 199, 65, 200, 66],
115
+ ],
116
+ ['o200k_base', 'trailing whitespace', 'hello \n ', [24912, 10190, 256]],
117
+ ['o200k_base', 'leading whitespace', ' hello', [256, 40617]],
118
+ ['p50k_base', 'space', 'a b', [64, 220, 275]],
119
+ ['p50k_base', 'tabs', 'a\t\tb\tc', [64, 197, 197, 65, 197, 66]],
120
+ [
121
+ 'p50k_base',
122
+ 'newlines',
123
+ 'a\n\nb\r\nc\n',
124
+ [64, 198, 198, 65, 201, 198, 66, 198],
125
+ ],
126
+ ['p50k_base', 'nbsp', 'a\u00a0b \u00a0c', [64, 1849, 65, 220, 1849, 66]],
127
+ [
128
+ 'p50k_base',
129
+ 'ideographic space',
130
+ 'a\u3000b\u3000\u3000c',
131
+ [64, 5099, 222, 65, 5099, 222, 5099, 222, 66],
132
+ ],
133
+ [
134
+ 'p50k_base',
135
+ 'line and paragraph separators',
136
+ 'a\u2028b\u2029c \u2028',
137
+ [64, 447, 101, 65, 447, 102, 66, 564, 101],
138
+ ],
139
+ [
140
+ 'p50k_base',
141
+ 'mixed unicode spaces',
142
+ 'x\u2003y\u2009\u200az\u202f\u205f',
143
+ [87, 447, 225, 88, 447, 231, 447, 232, 89, 447, 107, 46256, 253],
144
+ ],
145
+ [
146
+ 'p50k_base',
147
+ 'vertical tab and form feed',
148
+ 'a\u000bb\fc',
149
+ [64, 199, 65, 200, 66],
150
+ ],
151
+ [
152
+ 'p50k_base',
153
+ 'trailing whitespace',
154
+ 'hello \n ',
155
+ [31373, 50258, 198, 50257],
156
+ ],
157
+ ['p50k_base', 'leading whitespace', ' hello', [50257, 23748]],
158
+ ['r50k_base', 'space', 'a b', [64, 220, 275]],
159
+ ['r50k_base', 'tabs', 'a\t\tb\tc', [64, 197, 197, 65, 197, 66]],
160
+ [
161
+ 'r50k_base',
162
+ 'newlines',
163
+ 'a\n\nb\r\nc\n',
164
+ [64, 198, 198, 65, 201, 198, 66, 198],
165
+ ],
166
+ ['r50k_base', 'nbsp', 'a\u00a0b \u00a0c', [64, 1849, 65, 220, 1849, 66]],
167
+ [
168
+ 'r50k_base',
169
+ 'ideographic space',
170
+ 'a\u3000b\u3000\u3000c',
171
+ [64, 5099, 222, 65, 5099, 222, 5099, 222, 66],
172
+ ],
173
+ [
174
+ 'r50k_base',
175
+ 'line and paragraph separators',
176
+ 'a\u2028b\u2029c \u2028',
177
+ [64, 447, 101, 65, 447, 102, 66, 564, 101],
178
+ ],
179
+ [
180
+ 'r50k_base',
181
+ 'mixed unicode spaces',
182
+ 'x\u2003y\u2009\u200az\u202f\u205f',
183
+ [87, 447, 225, 88, 447, 231, 447, 232, 89, 447, 107, 46256, 253],
184
+ ],
185
+ [
186
+ 'r50k_base',
187
+ 'vertical tab and form feed',
188
+ 'a\u000bb\fc',
189
+ [64, 199, 65, 200, 66],
190
+ ],
191
+ [
192
+ 'r50k_base',
193
+ 'trailing whitespace',
194
+ 'hello \n ',
195
+ [31373, 220, 220, 220, 198, 220, 220],
196
+ ],
197
+ ['r50k_base', 'leading whitespace', ' hello', [220, 220, 23748]],
198
+ ]
199
+
200
+ describe('Unicode White_Space handling in the split patterns', () => {
201
+ // Keep this test first: the shared TextDecoder only strips a BOM on its very
202
+ // first decode, so later decodes in this file would hide a regression.
203
+ test('decode keeps U+FEFF tokens', () => {
204
+ const encoding = getEncoding('cl100k_base')
205
+ const feff = String.fromCodePoint(0xfeff)
206
+
207
+ // 3305 is the single token for the bytes EF BB BF
208
+ expect(encoding.decode([3305])).toBe(feff)
209
+ expect(encoding.decode([64, 3305, 65])).toBe(`a${feff}b`)
210
+ // 62619 is the single token for the bytes EF BB BF 0A
211
+ expect(encoding.decode([9906, 62_619])).toBe(`Hello${feff}\n`)
212
+ })
213
+
214
+ describe.each(unicodeWhiteSpaceCases)(
215
+ '%s: %j',
216
+ (encodingName, text, expected) => {
217
+ const encoding = getEncoding(encodingName)
218
+
219
+ test('encode matches tiktoken', () => {
220
+ expect(encoding.encode(text)).toEqual(expected)
221
+ })
222
+
223
+ test('countTokens agrees with encode', () => {
224
+ expect(encoding.countTokens(text)).toBe(expected.length)
225
+ })
226
+
227
+ test('decode round-trips', () => {
228
+ expect(encoding.decode(encoding.encode(text))).toBe(text)
229
+ })
230
+ },
231
+ )
232
+
233
+ describe.each(ordinaryWhiteSpaceCases)(
234
+ '%s: %s',
235
+ (encodingName, _label, text, expected) => {
236
+ const encoding = getEncoding(encodingName)
237
+
238
+ test('encode matches tiktoken', () => {
239
+ expect(encoding.encode(text)).toEqual(expected)
240
+ })
241
+
242
+ test('decode round-trips', () => {
243
+ expect(encoding.decode(encoding.encode(text))).toBe(text)
244
+ })
245
+ },
246
+ )
247
+ })
package/src/utfUtil.ts CHANGED
@@ -71,7 +71,18 @@ function isValidUTF8(bytes: Uint8Array): boolean {
71
71
  return true
72
72
  }
73
73
 
74
- const textDecoder = new TextDecoder('utf8', { fatal: false })
74
+ export function startsWithByteOrderMark(bytes: Uint8Array): boolean {
75
+ return (
76
+ bytes.length >= 3 &&
77
+ bytes[0] === 0xef &&
78
+ bytes[1] === 0xbb &&
79
+ bytes[2] === 0xbf
80
+ )
81
+ }
82
+
83
+ // `ignoreBOM: true` keeps a leading U+FEFF in the output instead of silently
84
+ // stripping it, so the bytes EF BB BF map to U+FEFF rather than to an empty string.
85
+ const textDecoder = new TextDecoder('utf8', { fatal: false, ignoreBOM: true })
75
86
 
76
87
  export function tryConvertToString(arr: Uint8Array): string | undefined {
77
88
  if (!isValidUTF8(arr)) {