contextwindow

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 13, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package contextwindow estimates token usage for a message history. The numbers are approximate — exact tokenization depends on the model's tokenizer and varies enough between providers that "good enough for a watermark" is the operative bar.

Two callers consume this:

  • The TUI status bar, which colors the token counter when usage crosses a configurable warn_threshold.
  • The auto-summarization trigger, which fires before the next turn when usage crosses auto_threshold.

Both treat the numbers as ratios, not absolute counts, so a 10–15% estimation error is harmless.

The companion question — how big IS the model's window — lives in the catalog package (catalog.ResolveWindow / WindowFor): the window is a per-model/per-deployment fact sourced from the catalog, the user's override, or a live probe, none of which belong in this leaf estimation package (which would otherwise drag the catalog's config/network deps in, and form an import cycle via adapter).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EstimateImage added in v0.4.0

func EstimateImage(img adapter.ImageBlock) int

EstimateImage returns the approximate token cost of a single image.

This deliberately does NOT scale with len(img.Data). A 4MB screenshot and a 200KB one of the same dimensions cost the model the same — byte size reflects compression, not context. Estimating from bytes would have scored one screenshot at a million tokens and triggered compaction constantly; ignoring images (the prior behavior) scored them at zero, so an image-heavy session could never trigger compaction at all. Pixel area is the measure both major providers actually bill on.

DecodeConfig reads only the header, so this stays cheap enough for the per-turn and status-bar call sites.

img.MediaType is honored: only formats with a registered header decoder can be dimension-read, and webp — which the read_file tool actively advertises — has none in the stdlib's image package. Rather than pull in a webp decoder (golang.org/x/image) just to read a width, we skip the sniff for any MediaType we can't decode and return the fallback. That's the same outcome the byte-sniff would have produced for an unregistered format, but explicit and stable rather than accidental.

func EstimateMessage added in v0.4.0

func EstimateMessage(m adapter.Message) int

EstimateMessage returns the approximate token cost of one message — content, tool-call arguments, and any attached images.

Callers that walk long histories (compaction's retain-point search) use this per-message form to avoid building a slice per call.

func EstimateText added in v0.3.0

func EstimateText(s string) int

EstimateText returns an approximate token count for an arbitrary string under the same heuristic EstimateTokens uses. /context calls this for the system-prompt and memory-file buckets where the input isn't a Message slice.

func EstimateTokens

func EstimateTokens(messages []adapter.Message) int

EstimateTokens returns an approximate token count for the given messages. Tool-call argument JSON and tool-result content are counted; role metadata is not (it's bounded and small).

func EstimateToolSchemas added in v0.3.0

func EstimateToolSchemas(tools []adapter.Tool) int

EstimateToolSchemas counts what the adapter advertises per tool: the tool name, description, and the JSON-serialized parameter schema. Mirrors what's actually sent on the wire so the /context Tools bucket matches the real cost.

Marshal errors fall back to a zero contribution for the offending tool — a malformed schema would have failed at registration time, so in practice this branch only fires for tools that pass nil/non-JSON schemas (which the adapter would reject anyway).

func SplitMessages added in v0.3.0

func SplitMessages(msgs []adapter.Message) (systemTokens, conversationTokens int)

SplitMessages partitions a message slice into the system-prompt prefix and the conversation body, returning estimated token counts for each bucket. The split is by role: every RoleSystem message (typically just one) goes into the system bucket, everything else into conversation. /context charges the two to different buckets so the user can see the always-present system overhead separately from the growing chat history.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL