Open value types, not enums
StopReason, ToolCallStatus, ToolKind, PermissionOptionKind, PlanEntryStatus,
PlanEntryPriority, and Role are now records wrapping a String, not Java enums. This means:
A value the running code has never heard of (because the peer speaks a newer protocol version)
still round-trips correctly: it deserializes to the same record type, just holding a string
.known() doesnât list. Treating these as enums was never source-compatible with a hypothetical
future protocol version; 0.80.0 makes that explicit in the type itself.
Unknown* variants
Several unions gained an explicit fallback member for a shape the running code doesnât recognize:
UnknownSessionUpdate, UnknownContentBlock, UnknownToolCallContent, UnknownPermissionOutcome,
UnknownSessionConfigOption, UnknownElicitationPropertySchema, UnknownMultiSelectItems,
UnknownAuthMethod (reading as AuthMethodAgent, in that specific case). Deserializing unrecognized
data into a typed fallback, rather than failing the whole message, is what makes it safe to run this
SDKâs client against a newer agent (or vice versa) without an immediate crash on day one of some
future protocol version.
No union in this SDK is sealed. Any instanceof chain over SessionUpdate, ContentBlock, or
similar must end with the Unknown* branch and a default, never assume the listed cases are
exhaustive:
_meta everywhere
Nearly every request, response, and notification carries an optional _meta: Map<String, Object>
field for implementation-specific extension data. Round-trip it even when you donât understand it:
if youâre building a proxy, forwarding _meta verbatim is what keeps it useful for the two
specific endpoints that defined it.
Error codes
0.80.0 aligns every error code with the ACP v1 schema exactly; the previous ad hoc choices are gone. The specâs own error-code page is thin (âDocumentation coming soonâ); the schemaâsErrorCode is the
source of truth, and this table is this SDKâs copy of it:
AcpError.getCode() returns the numeric code; getMessage() is the peerâs message text (plus any
detail from its error data), no longer [code=N] message; toString() still includes [code=N]
for logs. Use error.toException() on the receiving side and JSONRPCError.from(e) when answering,
rather than hand-building either direction.
Related
Concepts
Session updates and the ordering guarantee these open types flow through
Migration Guide
Every error-code and constructor-signature change from 0.18.0, in one table