> For the complete documentation index, see [llms.txt](/llms.txt). Every page on this site is also available as markdown at `<path>.md`.

# References & Glimpses

A reference is a named, TTL-bounded, content-addressed handle to a customer-owned value; a
glimpse is a small JSON summary that travels alongside it so agents can reason about the value
without dragging the full payload through every prompt.

```python
from pydantic import BaseModel

from flowai_harness import define_reference

class ProductSetPayload(BaseModel):
    product_ids: list[str]

ProductSet = define_reference(
    name="ProductSet",
    schema=ProductSetPayload,
    ttl_ms=60 * 60 * 1000,
    glimpse=lambda value: {
        "productCount": len(value.product_ids),
        "preview": value.product_ids[:3],
    },
)
```

## When to use a reference

Use a reference when an agent needs to pass a large or sensitive value between turns and you
don't want it embedded inline in every prompt. The Rust runtime (`flowai-runtime`) stores the
materialized value by content hash, retains it for `ttl_ms` milliseconds, and lets agents
fetch it on demand. The glimpse summary travels with the handle so the next agent can decide
whether it needs to fetch.

`define_reference(name=..., schema=..., ttl_ms=..., glimpse=...)` returns a frozen
[`ReferenceSpec`](/docs/reference/references#flowai_harness.references.ReferenceSpec). `schema`
accepts a Pydantic model class or any value that `normalize_schema(...)` accepts; the resolved
JSON Schema is what crosses the wire.

## Wire shape

The glimpse callable is Python-only — it is excluded from the spec dump because the runtime
does not need to inspect it. Hosts call it before storing a reference and pass the result
along.

```python
ProductSet.model_dump(by_alias=True, mode="json")
# {
#   "name": "ProductSet",
#   "schema": {"type": "object", "properties": {"product_ids": {...}}, ...},
#   "ttlMs": 3600000
# }
```

## Creating and reading references

Use `runtime.create_reference(...)` when host application code needs to store a typed
reference directly. Passing a `ReferenceSpec` runs its `glimpse` callback once at create time
and stores the computed glimpse beside the payload.

```python
payload = ProductSetPayload(product_ids=["sku-1", "sku-2", "sku-3"])

ref = await runtime.create_reference(ProductSet, payload)
# {"kind": "ProductSet", "id": "...", "glimpse": {"productCount": 3, "preview": [...]}}
```

The full host-side surface (`create_reference`, `resolve_reference`, `reference_glimpse`) is
documented in [Runtime](/docs/concepts/runtime#runtime-reference-apis).

Custom Python tools receive the same registry through `ctx.references`. This is the
recommended path for pointer-producing domain tools:

```python
from flowai_harness import define_tool

@define_tool("resolveProductSet", {"query": str}, approval="never")
async def resolve_product_set(args, ctx):
    products = await ctx.product_catalog.search_products(args["query"])
    payload = ProductSetPayload(product_ids=[product["id"] for product in products])
    ref = await ctx.references.create(ProductSet, payload)
    return {
        "productSetRef": {"kind": ref["kind"], "id": ref["id"]},
        "glimpse": ref["glimpse"],
    }
```

Agents with the `references` toolkit can later call `resolveRef` or `glimpseRef` with the
returned `{kind, id}` handle.

Use this decision rule:

- If a pointer-producing tool already returns both the `{kind, id}` handle and a useful
  `"glimpse"`, the agent normally should not call `glimpseRef` immediately.
- Use `glimpseRef` later when only the handle is available and a compact preview is enough.
- Use `resolveRef` when the full stored payload is needed.
- During approved plan execution, declared action references are hydrated automatically before
  dispatch, so executor agents should not call `resolveRef` manually in the normal execution
  path.

## Domain-specific glimpses

Glimpse fields are customer code. The runtime does not infer product, scope, pricing, or
other vertical-specific shapes. Write whatever summary helps your prompts; keep it small and
JSON-serializable:

```python
ProductSet = define_reference(
    name="ProductSet",
    schema=ProductSetPayload,
    ttl_ms=60 * 60 * 1000,
    glimpse=lambda value: {
        "productCount": len(value.product_ids),
        "preview": value.product_ids[:3],
        "hasEnterpriseSegment": any(pid.startswith("ENT-") for pid in value.product_ids),
    },
)
```

## The schema-neutral `glimpse(...)` helper

`flowai_harness.glimpse` is a small utility that normalizes whatever you hand it into a
JSON-compatible dict. It is useful inside tool handlers when you have already produced a
summary dict and only want to ensure values like `Decimal`, `datetime`, or Pydantic models
serialize cleanly. It is also a sensible fallback when you want a generic
`{count, sample}` view of a sequence.

```python
from decimal import Decimal
from flowai_harness import glimpse

glimpse({"totalRevenue": Decimal("1234.56"), "currency": "USD"})
# {"totalRevenue": "1234.56", "currency": "USD"}

glimpse(["a", "b", "c", "d", "e"])
# {"count": 5, "sample": ["a", "b", "c"]}
```

The exact normalization rules and the `max_items` parameter are documented in the
[`glimpse` reference](/docs/reference/glimpse).

<Callout type="info" title="Reference glimpse vs tool glimpse">

`define_reference(..., glimpse=...)` is for the reference itself — it runs when the host
stores the value. Tool handlers can also return a `"glimpse"` field in their result; the
`glimpse(...)` helper is the easiest way to build that dict consistently.

</Callout>

## See also

- [`define_reference` reference](/docs/reference/references#flowai_harness.references.define_reference)
- [`glimpse` helper reference](/docs/reference/glimpse#flowai_harness.glimpse.glimpse)
- [Tools](/docs/concepts/tools) — how tool handlers attach glimpses to their results.
