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...
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.
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. 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.
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.
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.
Custom Python tools receive the same registry through ctx.references. This is the
recommended path for pointer-producing domain tools:
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 callglimpseRefimmediately. - Use
glimpseReflater when only the handle is available and a compact preview is enough. - Use
resolveRefwhen the full stored payload is needed. - During approved plan execution, declared action references are hydrated automatically before
dispatch, so executor agents should not call
resolveRefmanually 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:
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.
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.
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.
See also
define_referencereferenceglimpsehelper reference- Tools — how tool handlers attach glimpses to their results.
Plans
A plan in the harness is a typed Pydantic schema that the planner emits and the executor consumes; when the action list is polymorphic, TaggedUnion builds a Pydantic...
Tools
Tools are async Python handlers wrapped in a ToolSpec. The @define_tool(...) decorator builds the spec and binds the handler in one step.
