Skip to content

Transform Example

Z-M-Huang edited this page Apr 27, 2026 · 2 revisions

Transform hook (reference)

A minimal reference transform. Demonstrates the canonical shape of a transform hook that reshapes a tool result before it reaches the LLM. Reference only — normative shape and rules live in Hooks (contract).


Purpose

A transform hook mutates payload in-flight between a turn stage's body and its consumers. This example truncates a Bash tool's stdout to a maximum length before the result lands in message history. Without it, a verbose command (e.g., ls -R /) can crowd the context window; with it, long outputs are trimmed with a clear marker.

This is a different kind of work than a Context Provider — a CP decides what to include at assembly time. A transform reshapes what already exists at a later stage. If you are contributing new content to the LLM request, write a CP, not a transform (per Hook Taxonomy § What hooks are not).


Shape

Field Value
Kind Hook.
subKind transform.
Attachment TOOL_CALL/post.
Firing sync (transforms are always sync — see Firing mode).
Validation severity Optional by default per Hooks § Validation severity. A load failure emits a warning; the session runs without the hook.
State slot None needed. Transforms should be deterministic.

Behavior

flowchart LR
    Body[TOOL_CALL body<br/>completed with stdout] --> Pre[read result.stdout]
    Pre --> Check{length ><br/>maxBytes?}
    Check -->|no| Pass[return result unchanged]
    Check -->|yes| Trunc["truncate + append marker:<br/>... truncated N bytes ..."]
    Trunc --> Out[return new result]
    Pass --> Next[next transform / observer]
    Out --> Next
Loading

Transform rules visible in the flow:

  1. The transform sees the tool result as payload.
  2. It returns a new payload. No side effects, no events — those belong to observers.
  3. The next transform in the slot's ordering manifest sees this transform's output.
  4. Transforms are deterministic. A transform that reads the wall clock or a random seed breaks replay determinism (see Hooks § Security notes — Transform hooks must be deterministic).

Config

Field Meaning Default
enabled Whether the hook participates. true.
maxBytes Maximum stdout length before truncation. 8192.
marker String appended to indicate truncation occurred. ... truncated {n} bytes ....
tools[] Tool names the transform applies to. ["Bash"].

What this transform does not do

  • It does not read env. Transforms on COMPOSE_REQUEST or TOOL_CALL that splice env values into LLM-visible payload violate LLM Context Isolation. That constraint applies here: the transform reshapes what is already visible, it does not add new-visible content.
  • It does not vote. A transform cannot refuse to return a payload. A transform that wants to block the call is a guard instead.
  • It does not call tools. Only the message loop calls tools.
  • It does not drive interaction. No approval prompts, no auth dialogs. See Hook Taxonomy § Hook vs. SM, hook vs. command.

When to copy this pattern

  • You need to reshape a payload (normalize case, redact, truncate, wrap).
  • The reshape is deterministic and depends only on its input.
  • The reshape belongs between stages, not at context-assembly time.

Do not use a transform for:

  • Adding new LLM-visible content — write a Context Provider with the appropriate capability declaration.
  • Recording what was reshaped for analytics — attach a sibling observer on the same slot.
  • Blocking the call — use a guard.

Related pages

Introduction

Reading

Core runtime

Contracts

Category contracts

Context

Security

Runtime behavior

Operations

Providers (bundled)

Integrations

Reference extensions

Tools

UI

Session Stores

Loggers

Providers

Hooks

Context Providers

Commands

Case studies

Flows

Maintainers

Clone this wiki locally