Raxol.AgentClientProtocol.Schema.AgentTypes (Raxol Agent Client Protocol v0.1.0)

Copy Markdown View Source

Agent-side types for the Agent Client Protocol: the initialize/ authenticate handshake, session lifecycle (session/new, session/load, session/set_mode, session/prompt, session/cancel), capability negotiation, and MCP server descriptors.

Every struct here carries an _meta map (default %{}) that is total on decode: unrecognized top-level wire keys, plus the contents of an explicit "_meta" wire object, are folded into it (via extract_meta/2) and re-emitted nested under the wire "_meta" key on encode (via put_meta/2, matching every sibling schema module's WireFields.emit_meta/2 convention), so round-tripping an object this library doesn't fully understand never loses data. from_json/1 never raises; it always returns {:ok, t} or {:error, reason}.

Known load-bearing string fields (cwd, sessionId, modeId, methodId) are type-checked via fetch/3, not just presence-checked via fetch/2: a wrong-typed value returns {:error, {:invalid_field, key, value}} rather than decoding the raw value through. A lenient presence-only decode on these fields would let e.g. a non-string sessionId reach a handler, changing the error class from -32602 Invalid params at decode to whatever the handler's own lookup produced. Unknown wire keys are unaffected -- they still fold into _meta via extract_meta/2 -- so this does not narrow forward-compat, only rejects nonsense on fields this module already claims to understand.

Cross-module references

PromptRequest.prompt is a list of Raxol.AgentClientProtocol.Schema.ContentBlock; InitializeRequest.client_capabilities / InitializeResponse reference Raxol.AgentClientProtocol.Schema.ClientTypes.ClientCapabilities; ClientRequest/ClientNotification reference Raxol.AgentClientProtocol.Schema.Ext.{ExtRequest, ExtNotification, ExtResponse}; protocol version decode uses Raxol.AgentClientProtocol.Schema.Version.coerce/1.

Note: ACP.SessionUpdate (the session/update notification's sessionUpdate-discriminated union) lives in upstream's lib/acp/client_types.ex, not agent_types.ex — it is intentionally NOT ported here. It lives as Raxol.AgentClientProtocol.Schema.SessionUpdate in its own file, session_update.ex, together with its variant payload structs (ContentChunk, CurrentModeUpdate, AvailableCommandsUpdate/AvailableCommand/AvailableCommandInput/ UnstructuredCommandInput). The {sessionId, update, _meta} envelope that wraps it for the wire is Raxol.AgentClientProtocol.Schema.LifecycleExtras.SessionNotification; this package has no AgentNotification routing union -- the session/update method is routed by its MethodTable row.

Ported from the MIT f1729/agent_client_protocol (c) 2025 f1729; see NOTICE.md.

Summary

Functions

Re-emit a struct's _meta bucket under the wire "_meta" key, omitted when empty -- matches the internal WireFields.emit_meta/2 helper (not part of the public docs; @moduledoc false), the convention every sibling module in this package (content.ex, plan.ex, tool_call.ex, client_types.ex) follows. The bucket is nested, never flattened onto the top-level wire object, so encode is symmetric with extract_meta/2, which folds an explicit "_meta" object on decode: a round trip preserves nested _meta content instead of promoting it to top-level fields.

Functions

put_meta(json, meta)

@spec put_meta(map(), map()) :: map()

Re-emit a struct's _meta bucket under the wire "_meta" key, omitted when empty -- matches the internal WireFields.emit_meta/2 helper (not part of the public docs; @moduledoc false), the convention every sibling module in this package (content.ex, plan.ex, tool_call.ex, client_types.ex) follows. The bucket is nested, never flattened onto the top-level wire object, so encode is symmetric with extract_meta/2, which folds an explicit "_meta" object on decode: a round trip preserves nested _meta content instead of promoting it to top-level fields.