See why the agent did what it did, turn by turn, with what it read, called and stated.
Whoever runs an AI agent needs to see why it did what it did: what it read from the memory, which tools it called and what they returned, what it showed the person, what it stated and what it decided. The turn record is that account, in one format for any agent framework. It is captured inside the agent’s process and sent later, so it never slows the answer. It pins the build the turn ran on, each prompt by version and the exact model, and that is why a real conversation can be replayed with the memory of the time, in your CI, without the content leaving your company. The content can stay in your storage: Niadra keeps the pointer and the hash. It is the receipt of every read extended to what the agent did with it.
How it works
Turn record
exampleturn 01J9K2 · voice agent · vendor B · 2:07 pm
- Input
- The customer’s words, on call 5521.
- Read
- The context in the voice view (version e7a1), the state block (version 0412) and the constraints block (cv_9c3).
- Called
- reschedule_visit(5521, "Sep 23 morning"): ok in 212 ms. Object shown: technician_visit 5521.
- Coordination
- Farewell: now. Effect farewell:call-5521 reserved and declared done.
- Stated
- Three claims: two matched, one with no origin, which gave way to the contract’s caveat.
- Said
- Points at the event of the 2:07 pm utterance. The text is not repeated here.
- Build
- prompts voice@v12 · model gpt-4.1-mini · the context compiler’s version and the pack’s hash, filled in by the SDK.
- Content
- Pointer mode: the values stay in your company’s bucket; here, the pointer and the sha256 of each one.
- Flags
- guard_acted: the check acted, so the turn goes to the kept tier, for 30 days.
- Replay
- Replayable: niadra replay --scenario … --runs 5, in your CI, with the tools answering from the record.
Captured in the agent’s process and sent later: the agent waited for nothing.
- Captured in the agent’s process, by copy, and sent in the background: a 25 KB tool result costs 0.05 ms at the 95th percentile
- Three content modes: stored at Niadra, a pointer to your storage only, or a hash only. A source may always send less, never more
- The record repeats no conversation text: it points at the events that already entered the memory
- The adapters open and close the turn for you: Google ADK, OpenAI Agents, LangGraph and LangChain in Python; LangChain, LangGraph, Mastra, Vercel AI SDK, OpenAI Agents JS, Google ADK and VoltAgent in TypeScript
- A flagged turn (an error, a check that acted, a handoff, a failed assertion) stays longer, and a complaint that arrives days later promotes the whole conversation
- Replay in your CI: scenarios of up to 50 turns with assertions, the tools answer from the record, the values never leave, and Niadra gives the statistical verdict
- The index of the kept turns enters your audit chain: one Merkle root per day, next to the receipts’ root
- On the Console’s Turns screen, every turn opens with what it read, called, stated and said, its flags, its pins and, when it cannot be replayed, why
from niadra import Niadra, phone
def shown(product):
fields = {"price_sale": product["price_sale"]}
return [{"ref": f"product:store:{product['sku']}", "fields": fields}]
@Niadra.tool("search_products", provenance=shown)
def search_products(sku: str) -> dict:
return CATALOG[sku]
niadra = Niadra(channel="whatsapp")
customer = phone(customer_phone)
with niadra.conversation(
thread_id, subject=customer, agent_id="store"
) as conversation:
conversation.customer(text)
build = Niadra.build(prompts={"store": "v3"}, model="gpt-4.1-mini")
with conversation.turn(build=build):
context = conversation.context(include=["constraints"])
# recorded: arguments, result, latency, the objects it showed
product = search_products("PX-4471")
reply = model(prompt_with(context, product))
# the record points at this event; the text is never repeated
conversation.agent(reply)
# Later, in your CI: the recorded turns run again with the pinned build
# niadra replay --agent app.agent:build_agent --scenario <id> --runs 5- Python
- TypeScript
From the SDK’s examples/turn_records.py: the tool records what it showed, the turn pins the build, and what the agent said enters as the event that already goes to the memory.
One memory, thirteen products
Any agent connects to the memory with three calls, in Python, TypeScript, HTTP or MCP, with a ready-made adapter for the most used voice and agent frameworks.
See the documentation(opens docs.niadra.com)- MemoryWhat was said and done, with a date, a source and evidence.
- IdentityPeople, companies and partners, recognized on any channel.
- PatternsWhat each customer repeats, computed from the history and delivered to every agent.
- StateWhat holds now for each customer, with the age and the source of every value.
- ContextWhat each agent needs to know before it starts.
- HistoryEverything that ever happened, for the agent to search.
- AlertsA signed webhook to your system the moment something happens.
- ClaimsWhat the agent may state, and the check of what it stated, with no extra model.
- CoordinationWho holds the customer now and what was already done, before an agent acts.
- MeasurementWhether each agent used the context it received.
- Turn recordYou are hereWhy the agent did what it did, turn by turn, and the replay in your CI.
- ConsoleWho read what, review, export and erasure.