|
Entropic 2.14.3
Local-first agentic inference engine
|
Track token usage across conversation. More...
#include <entropic/core/compaction.h>
Public Member Functions | |
| TokenCounter (int max_tokens) | |
| Construct a token counter. | |
| int | count_message (const Message &msg) const |
| Count tokens in a single message. | |
| int | count_messages (const std::vector< Message > &messages) const |
| Count total tokens in a message list. | |
| float | usage_percent (const std::vector< Message > &messages) const |
| Get usage as fraction of context window (0.0–1.0). | |
| void | clear_cache () |
| Clear the token count cache — retained as a no-op (gh#158). | |
Public Attributes | |
| int | max_tokens |
| Maximum context window size. | |
Track token usage across conversation.
Uses simple heuristic (~4 chars per token) for estimation. More accurate counting requires the model's tokenizer.
Definition at line 32 of file compaction.h.
|
explicit |
Construct a token counter.
| max_tokens | Maximum context window size. |
| max_tokens | Maximum context window size. @dg_internal |
Definition at line 26 of file compaction.cpp.
| void entropic::TokenCounter::clear_cache | ( | ) |
Clear the token count cache — retained as a no-op (gh#158).
Clear the token count cache — no-op since gh#158 (v2.13.0).
v1.8.4–v2.12.x memoized per-message counts in an unordered_map keyed by the ADDRESS of the Message. Two defects, and the second is what removed it. (1) A Message address is not an identity: the vector holding it reallocates on append and the allocator reuses freed slots, so a hit could answer for a message that no longer exists — a silent wrong count, never a crash. (2) The map was written from count_message() const with NO lock, so two concurrent runs (gh#158) or one run plus an entropic_context_usage call would insert into it simultaneously — heap corruption, not a wrong number.
The memo was never worth defending: count_text is one size() and one division, strictly cheaper than hashing a pointer and walking a bucket. So the cache is gone and counting is a pure function.
The method stays because four call sites in CompactionManager and ContextManager invalidate around a compaction, and a no-op keeps that intent legible rather than deleting the calls and leaving a future reader to wonder whether invalidation was forgotten.
Kept so the four invalidation call sites still read as "the counts these messages had are no longer valid". There is no cache to clear; counting is a pure function of the message content. See the header for why.
@dg_internal
Definition at line 102 of file compaction.cpp.
Count tokens in a single message.
| msg | Message to count. |
gh#158 (v2.13.0): pure, and unsynchronized ON PURPOSE because there is nothing left to synchronize. The address-keyed memo this used to write from a const method is gone — see TokenCounter::clear_cache for both reasons it had to be.
| msg | Message to count. |
Definition at line 56 of file compaction.cpp.
Count total tokens in a message list.
| messages | Messages to count. |
Definition at line 67 of file compaction.cpp.
Get usage as fraction of context window (0.0–1.0).
Get usage as fraction of context window.
| messages | Messages to measure. |
| messages | Messages to measure. |
Definition at line 83 of file compaction.cpp.
| int entropic::TokenCounter::max_tokens |
Maximum context window size.
Definition at line 94 of file compaction.h.