Vis

Context management

Long sessions can fill the model's context window with old file reads and tool results. Vis returns only selected tool output and can compress completed work into a summary without deleting your session history.

When to use

Folding settled work

When research is done, you can say:

Summarize what we learned and what remains open, then continue with the fix.

Vis calls a summary a fold. It replaces completed steps in the model's active context with conclusions, open questions, relevant files and test state. The originals stay saved, but the summary is what the model sees next. With session introspection enabled, you can inspect the raw transcript. A call to read_session() alone will not put folded steps back into the conversation.

Fold when a completed phase makes room for substantial new work. Vis provides a hint when the context budget calls for it. Folding after every small tool call can undermine prompt-cache reuse.

Reuse another session's findings

Ask Vis to consult another session if it has already investigated your problem. Vis brings back relevant findings and checks them against the current code, rather than copying a transcript. Consultation may incur model charges. It does not guarantee lower cost.

Example editing workflow

Ask Vis to find a function, change it and test it. It can keep file reads short, reuse intermediate results and fold the investigation before editing. A useful session helper can later become an extension if you request it, after reviewing its dependencies, preconditions and tests.

One tool, many functions

python_execution provides search, reads, edits and tests through Python. Only printed output returns to the model. Other results can stay in variables, and related work can share a call. Vis rebuilds session before each block with the latest turn, workspace roots, budget and extension context.

Discovery instead of catalogs

The prompt does not carry every function signature. apropos(pattern) matches a regular expression, ignoring case, against public symbol names in manifest order. Guides and skills also match by their title, opening, headings and When to use problems. doc(name) reads a contract, guide or skill when needed.

Reuse and refine session helpers

You can ask Vis to adapt a helper it already wrote:

Find the helper that summarized those rows, update it for the new columns, and check its callers.

A one-line docstring makes a helper easier to find with defs(). doc(name) returns the whole docstring. Helpers do not appear in apropos.

After each block, Vis saves your helpers and variables. A new sandbox restores them, for example after an idle timeout or a gateway restart. Sandbox state after a restart gives the limits.

If you define a name again, Vis replaces its saved copy. del name removes a helper or variable and frees its memory. Before you redefine or remove a name, check aliases, captured defaults and callers. Python references do not update automatically.

Addresses, not copies

grep and cat show a path @version header and number each line. patch takes that version and those line numbers, with all edits for a file in one call. If the file changed elsewhere after your read, patch moves your edits to the new lines. Changed lines or syntax errors reject the batch. Use Path.read_text() for data you will not edit.

Reference: folds and context budget

fold_session(key, gist) replaces settled steps with your summary. A string key selects one of these:

  • A turn: "t2".
  • A range: "t2/i4-i5".
  • Everything through an iteration: "-t3/i9".
  • Every turn through a turn: "-t3".
  • Settled steps since an iteration: "t2/i5-".

Commas join disjoint ranges. You cannot fold the live step. Without gist, the steps leave active context and no summary replaces them. History is still saved. There is no inline undo.

A turn key, or a range that covers a whole turn, also removes the request and answer of that turn. This applies only to turns before the current turn. A chat turn without tool calls folds the same way, so a long conversation of pasted text can fold too.

Iteration numbers start again in each turn. fold_session refuses a range that ends at an iteration that an earlier turn does not have. For example, it refuses "-t1/i16" when turn 1 has two iterations. The refusal names the key for every earlier turn.

session["utilization"] reports these values:

  • latest_measured_input_tokens is the latest request input that the provider measured, including context. It can include a rejected overflow request. It is not a live count, output usage or turn total.
  • auto_compress_above is the soft budget.
  • model_input_limit is the hard input limit for each request.
  • hint is conditional. It starts at 75% of the soft budget. From 90%, it asks for a fold before the next answer. Above 100%, it requires a fold while the pressure remains. After the first turn, it gives the exact key that folds every earlier turn that is not folded yet, so your earlier gists stay. A fold that covers an earlier fold replaces its gist.

The soft budget depends on the model: 250k tokens for Claude Opus models, 230k for GPT models and 200k for other models. It is never more than 90% of a known input limit, so smaller windows get a lower budget. For example, a 204k input limit gives a GPT model a budget of 183,600 tokens. When the input limit is unknown, the soft budget is 200k.

A fold receipt estimates the removed text locally. The next provider response measures the input change for the whole request, not only the savings of the fold. This needs no extra call. New tool output, the summary and other prompt changes also count.

Request health records fold_measurement with status: "measured", before_input_tokens, after_input_tokens and net_reduction_tokens. A positive net_reduction_tokens means less input, and a negative value means growth. All folds between two requests share one measurement and its fold_count.

The status is pending until the response arrives. It is unavailable, with a reason, in these cases:

  • Usage is missing.
  • The provider or model is unknown or changed.
  • The turn changes.

Detailed metrics are in session diagnostics, not in every model request.

Reference: session helpers

Helper lookup reference

For a helper named summarize_rows:

print(defs(pattern="summar|count"))
print(defs("summarize_rows"))
print(defs("summarize_rows", details=True))
  • defs() lists up to 20 helpers alphabetically, with a call hint and a docstring gist. Call hints are at most 120 characters, omit annotations and show only a default's type (=<int>), not its value. Hints are not source. Your variables follow, with type and size but never values. A row marks a restored helper and a value that is not saved. Match counts appear only when a pattern or a page hides rows.
  • defs(pattern="summar|count", limit=10, offset=0) matches names, first-line docstring gists and variable types with a case-sensitive regex. limit is 1–100, and offset is nonnegative. For more results, increase the offset or narrow the pattern.
  • defs("summarize_rows") returns unchanged source. For a variable, it returns the listing row. Check source for secrets before sharing.
  • defs("summarize_rows", details=True) returns origin, source SHA-256 and up to 20 source-derived global or captured names with types and presence. These hints do not prove dependencies or liveness. Default and decorator expressions are not analyzed. The digest identifies source, not argument defaults, captured values or mutable state.

See also

  • Context management API — context, usage and cache health from your own program.
  • Python sandbox — the interpreter the model's programs run in.
  • Extending Vis — turning a recurring helper into a tool.
  • Skills — instructions loaded when needed rather than included in every request.