Documentation
¶
Overview ¶
Package jq is a sandboxed wrapper around github.com/itchyny/gojq that evaluates a jq filter against a JSON input and returns the JSON-stringified result. It exists to narrow a remote tool's JSON result before it enters model context, so a large response does not blow the context budget or get truncated into an unparseable blob.
Sandboxing: the gojq query is constructed via gojq.Parse and run with gojq.Query.RunWithContext WITHOUT gojq.WithModuleLoader, gojq.WithInputIter, or gojq.WithEnvironLoader. The query therefore cannot read files, the environment, or stdin. A context deadline bounds pathological compute (e.g. `while(1; .+1)`); a context without a deadline is capped at DefaultTimeout.
Index ¶
Constants ¶
const DefaultTimeout = 5 * time.Second
DefaultTimeout is applied when the context passed to Run carries no deadline, so a pathological filter cannot run unbounded.
const MaxHeapGrowthBytes = 256 << 20
MaxHeapGrowthBytes bounds the heap a single Run may cause to grow before it is cancelled (CWE-770/400). The output cap (MaxOutputBytes) only fires AFTER each yielded value is materialized, so a filter that builds one huge value (e.g. `[range(1e8)]`) allocates it in full inside gojq before the cap is ever checked; without a memory bound, only DefaultTimeout limits it, and at gojq's allocation rate that is ~1 GiB before the deadline — enough to OOM a memory-constrained pod. gojq honours context cancellation during value construction, so Run watches heap growth and cancels the run once it crosses this budget. 256 MiB sits an order of magnitude above the MaxInputBytes (20 MiB) working set a legitimate filter needs while staying below a typical pod limit; a filter that needs more should narrow the remote call instead.
const MaxInputBytes = 20 << 20
MaxInputBytes is the cap on the size of the input passed to Run. It matches session.MaxToolResultBytes (20 MiB): if a remote tool's JSON result is larger than this, filtering it in memory is unsafe, and the caller should narrow the remote call rather than rely on jq.
const MaxOutputBytes = 100_000
MaxOutputBytes is the cap on the JSON-encoded size of the filtered result. The filtered subset a caller actually needs should be small; a jq filter that produces more than ~100 KiB is too broad and is rejected so it does not simply move the context-budget problem from the input to the output.
Variables ¶
This section is empty.
Functions ¶
func Run ¶
Run evaluates a jq filter against a JSON input and returns the JSON-stringified result.
Output shape: a jq filter can yield multiple values (e.g. `.items[]` yields one value per element). Run collects all yielded values and returns:
- exactly one value: that value, JSON-encoded (so a string result is returned as a quoted JSON string, e.g. `"hello"`),
- more than one value: a JSON array wrapping every value, JSON-encoded,
- zero values: the literal `null`.
The returned string is always JSON-shaped: every yielded value is passed through json.Marshal, so a single gojq string output is quoted rather than returned raw. Callers parsing the result with json.Unmarshal get a consistent shape.
Bounds:
- input <= MaxInputBytes (loud error if exceeded — don't load huge input),
- output <= MaxOutputBytes (loud error if the filtered result is huge),
- ctx should carry a deadline; if none, DefaultTimeout is applied.
All error messages are loud and self-describing (they are surfaced to a model/operator), wrapping the underlying cause where useful.
Types ¶
This section is empty.