Coverage for src/semware/utils/tokenizer.py: 100%
25 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-09 02:16 -0700
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-09 02:16 -0700
1"""Text tokenization utilities for handling context length limits."""
4import tiktoken
5from loguru import logger
8class TextTokenizer:
9 """Handles text tokenization and batching for embedding generation."""
11 def __init__(self, encoding_name: str = "cl100k_base"):
12 """Initialize tokenizer.
14 Args:
15 encoding_name: Name of the tokenizer encoding to use
16 """
17 self.encoding = tiktoken.get_encoding(encoding_name)
18 logger.info(f"Initialized tokenizer with encoding: {encoding_name}")
20 def count_tokens(self, text: str) -> int:
21 """Count the number of tokens in the text.
23 Args:
24 text: Input text
26 Returns:
27 Number of tokens
28 """
29 return len(self.encoding.encode(text))
31 def batch_text(self, text: str, max_tokens: int = 2000) -> list[str]:
32 """Split text into batches based on token count.
34 Args:
35 text: Input text to batch
36 max_tokens: Maximum tokens per batch
38 Returns:
39 List of text batches
40 """
41 if not text.strip():
42 return []
44 tokens = self.encoding.encode(text)
45 total_tokens = len(tokens)
47 if total_tokens <= max_tokens:
48 return [text]
50 # Split tokens into batches
51 batches = []
52 for i in range(0, total_tokens, max_tokens):
53 batch_tokens = tokens[i : i + max_tokens]
54 batch_text = self.encoding.decode(batch_tokens)
55 batches.append(batch_text)
57 logger.debug(
58 f"Split text into {len(batches)} batches ({total_tokens} total tokens)"
59 )
60 return batches
62 def batch_texts(self, texts: list[str], max_tokens: int = 2000) -> list[list[str]]:
63 """Batch multiple texts.
65 Args:
66 texts: List of texts to batch
67 max_tokens: Maximum tokens per batch
69 Returns:
70 List of batches for each text
71 """
72 return [self.batch_text(text, max_tokens) for text in texts]
75# Global tokenizer instance
76tokenizer = TextTokenizer()