Working name: AEP — Agent Event Protocol.
Expanded scope: asynchronous events, async tool lifecycle, context events, memory events, and agent coordination messages.
Every AEP event uses a common envelope.
{
"aep_version": "0.1",
"id": "evt_01JZ0000000000000000000000",
"type": "tool.call.progress",
"source": "tool:web_crawler",
"target": "agent:researcher",
"topic": "tasks.task_01",
"session_id": "sess_01",
"conversation_id": "conv_01",
"task_id": "task_01",
"correlation_id": "corr_01",
"causation_id": "evt_01JYZZZZZZZZZZZZZZZZZZZZZZ",
"created_at": "2026-07-09T10:00:00Z",
"expires_at": null,
"delivery": {
"mode": "at_least_once",
"sequence": 42,
"cursor": "stream_01:42"
},
"payload_schema": "https://schemas.axisrobo.com/tool.call.progress.v1.json",
"payload": {
"message": "Indexed 120 of 500 pages",
"progress": 0.24
}
}
aep_version: protocol versionid: globally unique event IDtype: event type using dotted namingsource: event producer identitycreated_at: event creation timestamppayload: event-specific bodytarget: intended consumer or audiencetopic: routing topicsession_id: runtime sessionconversation_id: conversation or interaction threadtask_id: related long-running taskcorrelation_id: logical operation correlation keycausation_id: event that caused this eventexpires_at: event relevance deadlinedelivery: delivery metadatapayload_schema: schema URI for validationEvent types use dotted namespaces:
domain.object.action
Examples:
event.acknowledgedsubscription.createdtool.call.requestedtool.call.progresstool.call.completedmemory.fact.invalidatedcontext.snapshot.readyagent.message.sentenvironment.observedsession.openedsession.readysession.heartbeatsession.closedsession.errorcapabilities.requestedcapabilities.declaredcapabilities.changedsubscription.requestedsubscription.createdsubscription.rejectedsubscription.cancelledsubscription.expiredevent.acknowledgedevent.rejectedevent.redeliveredevent.replayedevent.dead_letteredtool.call.requestedtool.call.acceptedtool.call.rejectedtool.call.startedtool.call.progresstool.call.outputtool.call.completedtool.call.failedtool.call.cancel.requestedtool.call.cancelledtool.call.timed_outtask.submittedtask.acceptedtask.startedtask.blockedtask.progresstask.outputtask.completedtask.failedtask.cancel.requestedtask.cancelledtask.timed_outcontext.updatedcontext.invalidatedcontext.snapshot.requestedcontext.snapshot.readycontext.retrieval.startedcontext.retrieval.completedcontext.retrieval.failedmemory.fact.addedmemory.fact.updatedmemory.fact.invalidatedmemory.episode.storedmemory.preference.updatedmemory.constraint.updatedmemory.summary.readymemory.retrieval.readyagent.message.sentagent.message.receivedagent.message.failedagent.request.createdagent.response.createdagent.decision.recordedenvironment.observedenvironment.changedenvironment.alertedenvironment.errorbelief.revisedbelief.conflict.detectedfreshness.expiredfreshness.window.changeddelegation.requesteddelegation.accepteddelegation.rejecteddelegation.handoff.completeddelegation.escalatedinterruption.requestedinterruption.acknowledgedinterruption.savedinterruption.resumedinterruption.cancelledcompensation.requestedcompensation.completedprovenance.attestation.addedprovenance.attestation.revokedprovenance.chain.truncatedAn async tool call is a task-like stream.
tool.call.requested
tool.call.accepted
tool.call.started
tool.call.progress
tool.call.output
tool.call.completed
Failure path:
tool.call.requested
tool.call.accepted
tool.call.started
tool.call.failed
Cancellation path:
tool.call.cancel.requested
tool.call.cancelled
A subscription describes what a consumer wants to receive.
{
"types": ["memory.*", "tool.call.*"],
"source": ["memory:main", "tool:web_crawler"],
"target": "agent:researcher",
"conversation_id": "conv_01",
"from_cursor": "stream_01:12",
"delivery_mode": "at_least_once"
}
Subscriptions may filter by:
The protocol should define delivery modes but leave implementation to transports.
Valid modes:
best_effortat_least_oncereplayableAEP should avoid promising strict exactly-once delivery. Instead, every event has a stable ID so consumers can deduplicate.
Errors should be events, not only transport failures.
Standard error payload:
{
"code": "tool_timeout",
"message": "Crawler exceeded the configured timeout",
"retryable": true,
"details": {}
}
AEP should version:
The envelope should remain stable across minor versions.
The first useful version should include: