Documentation
¶
Overview ¶
Package resultbudget holds a model client's tool results to its context budget (#1878).
The budget is a property of the MCP response to a model, not of any toolkit. It is enforced once, here, on every tool's result, and only when the caller is a model over MCP: a REST gateway call, a managed script's run and an admin call are never fitted, because a program that parses a response cannot read a cut one. Those callers meet only the real resource limits, a connection's read cap and the in-flight memory budget.
What is measured is the text of the result the client receives, which is what issue #1606 measured a client refusing.
Only a result the model can recover the rest of is ever cut. A tool whose result is data with an export equivalent -- a response body, a GraphQL answer, a query's rows -- implements toolkit.ResultFitter, cuts in its own shape, flags the cut and hands back the export call that returns the whole. Every other result reaches the model whole: a knowledge page, a tool's help, a prompt or an uploaded document cut in half has no way back to the rest, and a model reasoning from half a manual does worse than one whose client spills an oversized result to a file it can still read. A fitter that cannot cut a result recoverably declines, and that result is left whole too.
It lives in its own package so the platform facade gains no field or method for it.
Index ¶
Constants ¶
const DefaultMaxBytes = 32 * 1024
DefaultMaxBytes is the context budget a tool result is held to when the configuration names none. Issue #1606 measured a 64,213-character tool result refused by a client and spilled to a file, so the ceiling is under 64 KiB; 32 KiB leaves room under it for a client stricter than the one measured.
Variables ¶
This section is empty.
Functions ¶
func Capture ¶
func Capture() mcp.Middleware
Capture records the tool's own result for Middleware. It is registered innermost, next to the handler; a call Middleware does not fit carries no recorder, and Capture does nothing.
func Middleware ¶
func Middleware(cfg Config, lookup FitterLookup) mcp.Middleware
Middleware fits a model client's tools/call results to its budget, those of the tools that have a fitter. It reads the PlatformContext the tool-call middleware writes, so it must be inner to it. It sits outer to enrichment and the call reference, so what it measures is what the client receives; Capture, innermost, records which part of that is the tool's own, and only that part is shaped by the tool's fitter.
func TextSize ¶
func TextSize(res *mcp.CallToolResult) int
TextSize is the size of a result's text: what a client renders.
Types ¶
type Config ¶
type Config struct {
// MaxBytes is the most of a rendered tool result a model client is
// handed. Zero takes DefaultMaxBytes.
MaxBytes int `yaml:"max_bytes"`
// PerTool overrides MaxBytes for the named tools.
PerTool map[string]int `yaml:"per_tool"`
}
Config is the `tools.result_budget` section.
type FitterLookup ¶
type FitterLookup func(tool string) toolkit.ResultFitter
FitterLookup returns the fitter a tool's toolkit provides, or nil when it provides none, in which case the tool's results are never cut.
func RegistryLookup ¶
func RegistryLookup(reg *registry.Registry) FitterLookup
RegistryLookup resolves a tool's fitter through the toolkit registry. It resolves per call rather than once, because a toolkit can be added after startup (a first connection of a kind saved through the admin API).