LaserData Cloud
Laser SDK

AGDX

The portable data and agent contract underneath Laser SDK.

AGDX (Agent Data Exchange Protocol) defines records and behavior for Laser SDK. It covers streaming, managed data, and agent coordination on a durable log. The SDK records model provenance. It does not call models.

AGDX assumes a durable partitioned log with offsets. Laser SDK implements it on Apache Iggy. AGDX defines portable data and behavior. Iggy provides transport, retention, and consumer groups.

Rust, Python, and TypeScript use VSR (Viewstamped Replication Revisited). VSR handles transport and replication below AGDX. It does not change AGDX envelopes, headers, command codes, or fixtures. Classic Iggy transport is unsupported.

This page covers the architecture and application rules. The full specification and its docs/agdx.md source define exact fields, limits, codes, and byte layout.

One contract, five layers

Edges
A2A, MCP, and AG-UI adapters
Fabric
Envelope, runtime, coordination, memory
Platform
Streaming, views, state, graph
Wire
CBOR types, dictionaries, limits, fixtures
Substrate
Durable message-streaming log
LayerOwnsCan be used alone
SubstrateDurable partitions, offsets, retention, consumer groups, pull-based readsLaser SDK ships Apache Iggy
WirePortable types, named-field CBOR, dictionaries, limits, capability shapes, fixturesYes, by an independent port
PlatformPublish and consume, projections and query, key-value, forks, graphYes, with no agent concepts
FabricAgent envelopes, reliable consumers, coordination, context, memory, governanceYes, with no public edge protocol
EdgesA2A, MCP, and AG-UI mappingsOnly when an external client needs that contract

The log remains the source of truth. Projections, query indexes, working state, graph data, run status, and agent registries are derived views or recorded conventions, not independent stores synchronized by application glue.

Envelope anatomy

Every typed agent record carries one named-field CBOR AgentEnvelope. The Apache Iggy binding keeps only the information needed before decoding out of band.

01
Publisher
02
One durable record
Routing metadata
AgentEnvelope CBOR
03
Conversation partition
04
Consumer
Pull, validate, handle, commit

Each field has one authoritative location. An agent record stamps agdx.ct, agdx.av, gen_ai.conversation.id, and optional agdx.to outside the envelope.

The envelope owns source, cause, correlation, deadlines, idempotency, operation details, and body. Generic records may use the wider provenance header set.

command {
  kind:         command
  record:       01J...
  conversation: 01J...        # partition key and trace identity
  source:       planner       # a claim unless verified
  target:       summarizer
  correlation:  01J...        # request and reply pairing
  operation:    summarize
  body:         <bytes>       # decoded using agdx.ct
  signature:    <optional>
}
Field familyFieldsPurpose
Identity and routingkind, record, conversation, source, targetWhat this is, who claims to have sent it, where it belongs
Causalitycause, cause_at, correlationParent record, optional native log position, request and reply pairing
Chunk lifecyclechannel, sequence, last, finish_reasonOrdered streaming and deterministic reassembly
Executionoperation, tool, task_state, deadline_micros, idempotency_keyWhat is happening and which safety constraints apply
Contentbody, content type headerOpaque payload bytes and their codec
Accounting and policyusage, metadataAdvisory token usage and pinned policy or routing context
Evolution and integritymust_understand, signatureStrict feature handling and optional verified authorship

Machine ids are 128-bit values displayed as 26-character Crockford base32 strings. In the CBOR envelope they are fixed 16-byte big-endian byte strings. cause is the portable parent identity. cause_at is an optional Apache Iggy log-position locator for efficient local navigation.

The kind determines which fields are required or invalid. The wire validator, SDK constructors, and receivers all enforce the same matrix.

KindRequired coreMeaning
commandrecord, conversation, source, correlation, bodyRequests a reply or an effect. A fire-and-forget command is invalid
responserecord, conversation, source, correlation, bodyAnswers the command carrying the same correlation
eventrecord, conversation, source, bodyAnnounces something and expects no reply
chunkconversation, source, correlation, channel, sequence, bodyCarries one ordered part of chat, reasoning, or tool_args
statusrecord, conversation, source, operationCarries task, card, progress, quarantine, or unquarantine state
errorrecord, conversation, source, correlation, bodyTerminates a request, and optionally a chunk channel, with a typed error

status with operation task also requires a correlation and task state. A chunk requires its purpose on sequence 0, forbids the purpose on later chunks, and carries usage only on the terminal chunk. Construct envelopes through the typed SDK verbs instead of assembling raw maps.

Command and stream lifecycle

01
Append command
02
Read from offset
03
Open channel
04
Append chunks
05
End channel
06
Replay correlation
07
Reassemble and commit

A chunk stream is grouped by channel and ordered by sequence inside one conversation partition. Reassembly starts at zero and drops duplicate sequences. A gap ends the stream. Only the first terminal is accepted.

Offsets provide resume state. Reader-local gap and abandoned outcomes are never written back to the raw log.

Produce the same command in every SDK

const conversation = ConversationId.new()
const correlation = CorrelationId.parse(
  conversation.toString()
)

const record = await laser
  .agdx(
    AgentTopic.Commands,
    AgentId.new("planner"),
    conversation
  )
  .command(correlation, utf8("summarize incident 42"))
  .withOperation("summarize")
  .send()
let conversation = ConversationId::new();
let correlation =
    CorrelationId::from_u128(conversation.as_u128());

let record = laser
    .agdx(
        AgentTopic::Commands,
        "planner".parse()?,
        WireConversationId::from(conversation),
    )
    .command(
        correlation,
        b"summarize incident 42".to_vec(),
    )
    .with_operation("summarize")
    .send()
    .await?;
conversation = ls.new_conversation_id()
correlation = ls.new_correlation_id()

record = await laser.agdx(
    ls.Topics.COMMANDS,
    "planner",
    conversation,
).command(
    correlation,
    b"summarize incident 42",
    operation="summarize",
)

All three calls publish the same logical command envelope and return its minted record id. The worker replies with respond using the same correlation, or opens a chunk stream when it needs incremental output.

Delivery, ordering, and replay

  • At least once: handlers commit their consumer offset only after successful processing. A crash before the commit causes replay.
  • Ordered per conversation: agent records use the conversation id as the partition key. Independent conversations can run across partitions in parallel.
  • Exactly once is application behavior: use an idempotency key and a durable processed-key store around the business effect. It is not a wire delivery mode.
  • Acknowledgement is an offset commit: AGDX adds no ack, nack, visibility timeout, priority, or broker-managed retry protocol.
  • Dead lettering is explicit: the runtime publishes a capsule containing the original encoded envelope, source position, reason, attempt count, and optional detail.
  • Large bodies use claim-check: BodyRef names external bytes and pins their size and SHA-256 digest, so a consumer verifies what it retrieves.

Trust boundary

Agent-written fields are claims until verified. Routing does not grant access.

SignalSafe interpretation
source, target, usage, cost, policy metadataAdvisory on a shared unsigned topic
Verified envelope signatureProves the enrolled principal signed the canonical envelope
Signature contextAlso binds the out-of-band content type and agent version
Write-exclusive Iggy topic with ACLsEstablishes authorship through topology
Server-stamped user on managed commandsTrusted input to capability RBAC
Fence token checked by the state storeRejects a stale lease holder before an effect

target narrows routing but does not grant access. Token usage and cost are advisory accounting. A privileged control fact such as quarantine requires a valid operator signature.

Delegated work carries on_behalf_of inside signed envelope metadata. Authorization intersects the agent's grants with the user's grants.

More than agent messages

AGDX defines three data surfaces over one authenticated connection.

SurfaceOperationsSource of truth
Streamingpublish, consume, typed envelopes, replay, batchingApache Iggy log
Materialized viewsprojections, schemas, query, change feed, graph traversalDeterministic views derived from log records
Working statekey-value, compare-and-swap, fenced writes, leases, copy-on-write forksOrdered mutations recorded through the platform

Memory is a facade over those primitives, not a separate wire command family. remember publishes a typed memory record, recall reads the best available view, graph relationships use the graph surface, and context scopes apply the conversation lens consistently.

Capability negotiation

At connection time the SDK probes hello. The reply advertises the managed plane, per-surface operation versions, feature bits, materialization backends, and the deployment's resolved AGDX topic topology.

  • An unavailable surface returns a typed Unsupported error.
  • A mismatched operation version fails locally before the request is sent.
  • Additive behavior that could be silently ignored, such as stronger query consistency, is refused unless explicitly advertised.
  • Subfeatures default off. A server must never advertise a guarantee it cannot honor.
  • Standalone VSR-enabled Apache Iggy serves streaming and the log-backed agent fabric. Managed commands require an advertised capability. Laser Stack supplies those capabilities through laser-plane.

This makes capability discovery part of correctness, not a marketing feature list. Applications can branch on laser.capabilities() without probing through failures or manually supplying a capability set.

Interop is an edge mapping

External agent protocols do not replace AGDX inside the system. A bridge translates at the boundary, while internal agents and services continue to read and append durable records.

The runtime path stays compact: external client, edge adapter, AGDX command or event, internal agent, AGDX reply or stream, then edge response mapping. The durable log remains between every internal producer and consumer.

External contractAGDX mapping
A2A message and task lifecycleCommand on a fresh task conversation, then response, error, and task-status records
MCP tools/callCommand carrying the tool name and correlated response or error
AG-UI chat, reasoning, and tool callsChunk streams rendered as frontend events
AG-UI shared statestate_snapshot and RFC 6902 state_delta events
Human approvalOrdinary command and response through request_input and respond_input

Map shared semantics into envelope fields. Keep protocol-specific data byte-identical in the body. Every bridge appends its id to bridge_hops and rejects messages that already contain it. This prevents translation loops. See Interop for the bridge APIs.

Encoding and conformance

Independent ports interoperate by preserving a small set of strict invariants:

  • Every wire payload uses named-field CBOR through one encoder.
  • A payload is exactly one CBOR item. Trailing bytes, corrupt known fields, and wrong known types fail decoding.
  • Unknown fields are ignored for additive evolution. Unknown dictionary codes remain representable instead of failing the whole record.
  • Optional fields are omitted, not encoded as empty placeholders.
  • Envelope ids are 16-byte big-endian values. The duplicate Apache Iggy Uint128 routing header uses Iggy's little-endian typed representation.
  • The per-kind validity matrix is checked before publish and after decode.
  • Positive fixtures pin accepted bytes. Negative fixtures pin rejected shapes. Decode, validate, and re-encode must remain byte-identical.

The runtime-free laser-wire crate owns the contract and golden fixtures. All clients use the same envelope rules and scenarios.

Transport, cryptography, clocks, and ID generation remain outside this crate.

Status

AGDX is pre-1.0. The built core and VSR Iggy binding define the current contract. Roadmap sections are proposals. Breaking wire changes require an operation-version decision and fixture updates in every SDK.

On this page