driverprotocol

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 14, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package driverprotocol defines AgentAPI Doctor's stable out-of-process driver control protocol.

Control messages are JSON-RPC 2.0 objects carried as one JSON value per NDJSON line. Large observation payloads are carried on a separately negotiated, length-prefixed companion stream; drivers never mint CAS references themselves.

Index

Examples

Constants

View Source
const (
	// JSONRPCVersion is the only JSON-RPC envelope version accepted by v1.
	JSONRPCVersion = "2.0"

	// MaxControlFrameBytes bounds a JSON value before the NDJSON line ending.
	MaxControlFrameBytes = 1 << 20
	// DefaultMaxDataFrameBytes bounds a payload on the companion data plane.
	DefaultMaxDataFrameBytes = 256 << 10
)

Variables

View Source
var (
	ErrEmptyControlFrame     = errors.New("empty driver control frame")
	ErrMultilineControlFrame = errors.New("driver control frame must be one NDJSON line")
	ErrControlFrameTooLarge  = errors.New("driver control frame exceeds 1 MiB")
	ErrDataFrameTooLarge     = errors.New("driver data frame exceeds 256 KiB")
)

Functions

func DecodeParamsStrict

func DecodeParamsStrict(raw json.RawMessage, destination any) error

DecodeParamsStrict decodes method params or a result into a public typed contract. It rejects duplicate and unknown fields and requires one JSON value. Callers should pass a pointer to the destination.

func EncodeControlFrame

func EncodeControlFrame(message Message) ([]byte, error)

EncodeControlFrame validates and RFC-8785-canonicalizes a message, then appends exactly one LF for NDJSON transport.

func ValidateControlFrameSize

func ValidateControlFrameSize(size int) error

ValidateControlFrameSize applies the fixed v1 control-plane bound.

func ValidateDataFrameSize

func ValidateDataFrameSize(size int) error

ValidateDataFrameSize applies the default companion data-plane frame bound. A negotiated lower limit must be checked by the caller as well.

Types

type ActiveInvocation

type ActiveInvocation struct {
	InvocationID    publicschema.InstanceID
	AttemptID       publicschema.InstanceID
	LastSequence    uint64
	HasObservation  bool
	CancelRequested bool
}

ActiveInvocation is a non-sensitive state-machine snapshot.

type CancelParams

type CancelParams struct {
	InvocationID   publicschema.InstanceID `json:"invocation_id"`
	Reason         string                  `json:"reason"`
	DeadlineMillis uint64                  `json:"deadline_millis"`
}

CancelParams asks the driver to begin cancellation. DeadlineMillis is a relative time budget supplied by Core; an acknowledgement is not terminal.

func (CancelParams) Validate

func (params CancelParams) Validate() error

type CancelResult

type CancelResult struct {
	Acknowledged bool `json:"acknowledged"`
}

CancelResult acknowledges receipt only. Termination is represented solely by driver.completed.

type Capabilities

type Capabilities struct {
	Protocols      []string `json:"protocols"`
	Operations     []string `json:"operations"`
	Streaming      bool     `json:"streaming"`
	Cancellation   bool     `json:"cancellation"`
	RetryObserved  bool     `json:"retry_observed"`
	Concurrency    bool     `json:"concurrency"`
	MaxConcurrency uint32   `json:"max_concurrency"`
}

Capabilities declares what the driver can execute; it is not evidence that the target supports the same capability.

type CapabilitiesParams

type CapabilitiesParams struct{}

CapabilitiesParams is intentionally empty. A later version must add fields through a separately versioned contract rather than accepting typos.

type CapabilitiesResult

type CapabilitiesResult struct {
	Capabilities Capabilities `json:"capabilities"`
}

CapabilitiesResult returns the current prepared driver's capabilities.

type CompanionStreamRef

type CompanionStreamRef struct {
	StreamID string `json:"stream_id"`
}

CompanionStreamRef identifies a negotiated data-plane stream. It is not a CAS reference.

type CompletedParams

type CompletedParams struct {
	InvocationID  publicschema.InstanceID `json:"invocation_id"`
	AttemptID     publicschema.InstanceID `json:"attempt_id"`
	Status        TerminalStatus          `json:"status"`
	LastSequence  *uint64                 `json:"last_sequence,omitempty"`
	SummaryDigest publicschema.Digest     `json:"summary_digest"`
}

CompletedParams terminates an invocation. LastSequence is nil when no observation was emitted and otherwise must equal the last observed value.

func (CompletedParams) Validate

func (params CompletedParams) Validate() error

type DataFrameHeader

type DataFrameHeader struct {
	InvocationID publicschema.InstanceID `json:"invocation_id"`
	AttemptID    publicschema.InstanceID `json:"attempt_id"`
	StreamID     string                  `json:"stream_id"`
	Sequence     uint64                  `json:"sequence"`
	Length       uint32                  `json:"length"`
	Final        bool                    `json:"final"`
}

DataFrameHeader precedes one companion-pipe payload.

func (DataFrameHeader) Validate

func (header DataFrameHeader) Validate() error

Validate checks identity and the default data-frame bound.

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

Decoder reads strict NDJSON control frames without allowing an unbounded line allocation. After an oversized line, it drains through the delimiter so a caller may continue with the next frame.

func NewDecoder

func NewDecoder(reader io.Reader) *Decoder

NewDecoder creates an NDJSON control decoder.

func (*Decoder) Decode

func (decoder *Decoder) Decode() (Message, error)

Decode reads one control message. A final line without LF is accepted.

type DriverIdentity

type DriverIdentity struct {
	Name           string              `json:"name"`
	Version        string              `json:"version"`
	SDKName        string              `json:"sdk_name,omitempty"`
	SDKVersion     string              `json:"sdk_version,omitempty"`
	ClientName     string              `json:"client_name,omitempty"`
	ClientVersion  string              `json:"client_version,omitempty"`
	RuntimeName    string              `json:"runtime_name"`
	RuntimeVersion string              `json:"runtime_version"`
	OS             string              `json:"os"`
	Architecture   string              `json:"architecture"`
	ArtifactDigest publicschema.Digest `json:"artifact_digest"`
	LockfileDigest publicschema.Digest `json:"lockfile_digest,omitempty"`
}

DriverIdentity pins all executable and client inputs relevant to an observation. Optional SDK/client fields are omitted for the built-in raw driver.

type Encoder

type Encoder struct {
	// contains filtered or unexported fields
}

Encoder writes canonical NDJSON control frames.

func NewEncoder

func NewEncoder(writer io.Writer) *Encoder

NewEncoder creates an NDJSON control encoder.

func (*Encoder) Encode

func (encoder *Encoder) Encode(message Message) error

Encode writes exactly one complete control frame.

type ErrorClass

type ErrorClass string

ErrorClass is the stable machine-readable failure taxonomy. It is separate from the numeric JSON-RPC error code.

const (
	ErrorUnsupportedRPCVersion ErrorClass = "unsupported_rpc_version"
	ErrorInvalidState          ErrorClass = "invalid_state"
	ErrorInvalidRequest        ErrorClass = "invalid_request"
	ErrorPermissionDenied      ErrorClass = "permission_denied"
	ErrorBudgetExceeded        ErrorClass = "budget_exceeded"
	ErrorCapabilityMismatch    ErrorClass = "capability_mismatch"
	ErrorDriverInternal        ErrorClass = "driver_internal"
	ErrorCancellationTimeout   ErrorClass = "cancellation_timeout"
	ErrorMalformedObservation  ErrorClass = "malformed_observation"
	ErrorArtifactMismatch      ErrorClass = "artifact_mismatch"
)

func ErrorClassOf

func ErrorClassOf(err error) (ErrorClass, bool)

ErrorClassOf extracts a stable class from a protocol error.

type ErrorData

type ErrorData struct {
	Class   ErrorClass      `json:"class"`
	Details json.RawMessage `json:"details,omitempty"`
}

ErrorData carries the stable class and optional bounded structured details. Details remain application data; core error fields are strict.

type ExactInputHandle

type ExactInputHandle struct {
	Kind  string `json:"kind"`
	Value string `json:"value"`
}

ExactInputHandle describes an invocation-scoped input channel. The handle value is operational state and must not be copied to evidence or reports.

type HelloParams

type HelloParams struct {
	CoreVersionRange VersionRange `json:"core_version_range"`
}

HelloParams contains the Core's supported Driver API range.

func (HelloParams) Validate

func (params HelloParams) Validate() error

type HelloResult

type HelloResult struct {
	DriverVersionRange   VersionRange   `json:"driver_version_range"`
	Identity             DriverIdentity `json:"identity"`
	Capabilities         Capabilities   `json:"capabilities"`
	RequestedPermissions []Permission   `json:"requested_permissions"`
}

HelloResult binds the driver identity, API range, capabilities, and requested permissions returned by the handshake.

func (HelloResult) Validate

func (result HelloResult) Validate() error

type InvokeParams

type InvokeParams struct {
	InvocationID publicschema.InstanceID `json:"invocation_id"`
	AttemptID    publicschema.InstanceID `json:"attempt_id"`
	Operation    string                  `json:"operation"`
	Input        ExactInputHandle        `json:"ephemeral_exact_input_handle"`
}

InvokeParams starts one invocation. Base v1 state-machine validation is serial; negotiated concurrency requires a higher-level dispatcher with one Machine per active invocation.

func (InvokeParams) Validate

func (params InvokeParams) Validate() error

type Machine

type Machine struct {
	// contains filtered or unexported fields
}

Machine validates one serial Driver RPC lifecycle. It is safe for concurrent calls, but concurrency-capable drivers must use a higher-level dispatcher that assigns a Machine to each invocation rather than weakening sequence and terminal checks here.

Example
machine := NewMachine()
_ = machine.AcceptHello()
_ = machine.AcceptPrepare()
fmt.Println(machine.State())
Output:
PREPARED

func NewMachine

func NewMachine() *Machine

NewMachine starts in NEW.

func (*Machine) AcceptHello

func (machine *Machine) AcceptHello() error

AcceptHello advances NEW to HELLO after a successful hello exchange.

func (*Machine) AcceptPrepare

func (machine *Machine) AcceptPrepare() error

AcceptPrepare advances HELLO to PREPARED after Core and the driver agree on the exact plan and permission subset.

func (*Machine) Active

func (machine *Machine) Active() (ActiveInvocation, bool)

Active returns a copy of the current invocation, if any.

func (*Machine) Apply

func (machine *Machine) Apply(message Message) error

Apply validates and applies a decoded Driver request or notification. A response has no method correlation and must be handled by the caller's request table; applying one directly is rejected.

func (*Machine) BeginInvocation

func (machine *Machine) BeginInvocation(params InvokeParams) error

BeginInvocation advances PREPARED to INVOKING and binds sequence and terminal validation to the invocation and attempt IDs.

func (*Machine) CheckCapabilities

func (machine *Machine) CheckCapabilities() error

CheckCapabilities validates a capability query without changing state.

func (*Machine) Complete

func (machine *Machine) Complete(params CompletedParams) error

Complete validates the unique terminal notification and advances INVOKING back to PREPARED. A completed invocation ID cannot be reused in this driver session.

func (*Machine) Observe

func (machine *Machine) Observe(params ObservationParams) error

Observe validates one driver.observation notification. Sequence values need not be contiguous, but each must be strictly greater than the previous one.

func (*Machine) RequestCancel

func (machine *Machine) RequestCancel(params CancelParams) error

RequestCancel records a cancellation request. It deliberately remains in INVOKING: cancel acknowledgement is not termination; only Complete may end the invocation.

func (*Machine) Reset

func (machine *Machine) Reset() error

Reset clears driver-owned prepared session data. It cannot run while an invocation is active and does not relax invocation-ID uniqueness.

func (*Machine) Shutdown

func (machine *Machine) Shutdown() error

Shutdown advances PREPARED to the terminal SHUTDOWN state.

func (*Machine) State

func (machine *Machine) State() State

State returns the current lifecycle state.

type Message

type Message struct {
	JSONRPC string          `json:"jsonrpc"`
	ID      json.RawMessage `json:"id,omitempty"`
	Method  Method          `json:"method,omitempty"`
	Params  json.RawMessage `json:"params,omitempty"`
	Result  json.RawMessage `json:"result,omitempty"`
	Error   *RPCError       `json:"error,omitempty"`
}

Message is one strict JSON-RPC 2.0 control frame. ID is retained as raw JSON so string and numeric IDs round-trip without lossy conversion. An absent ID is a notification; an explicit JSON null is still an ID and is rejected for requests because null cannot be correlated safely.

func DecodeControlFrame

func DecodeControlFrame(line []byte) (Message, error)

DecodeControlFrame decodes one complete NDJSON line. A single trailing LF or CRLF is accepted; embedded physical newlines are rejected. Duplicate JSON members, concatenated values, invalid UTF-8, unknown envelope fields, and unknown Driver RPC methods fail closed.

func (Message) Kind

func (message Message) Kind() (MessageKind, error)

Kind validates the envelope shape and returns its JSON-RPC kind.

type MessageKind

type MessageKind uint8

MessageKind distinguishes JSON-RPC requests, notifications, and responses.

const (
	MessageInvalid MessageKind = iota
	MessageRequest
	MessageNotification
	MessageResponse
)

type Method

type Method string

Method is a stable Driver RPC method or notification name.

const (
	MethodHello        Method = "driver.hello"
	MethodPrepare      Method = "driver.prepare"
	MethodCapabilities Method = "driver.capabilities"
	MethodInvoke       Method = "driver.invoke"
	MethodCancel       Method = "driver.cancel"
	MethodReset        Method = "driver.reset"
	MethodShutdown     Method = "driver.shutdown"
	MethodObservation  Method = "driver.observation"
	MethodCompleted    Method = "driver.completed"
)

type ObservationParams

type ObservationParams struct {
	InvocationID publicschema.InstanceID `json:"invocation_id"`
	AttemptID    publicschema.InstanceID `json:"attempt_id"`
	Sequence     uint64                  `json:"sequence"`
	Kind         string                  `json:"kind"`
	MonotonicNS  uint64                  `json:"monotonic_ns"`
	Payload      json.RawMessage         `json:"payload,omitempty"`
	DataStream   *CompanionStreamRef     `json:"data_stream,omitempty"`
}

ObservationParams is the only semantic observation notification.

func (ObservationParams) Validate

func (params ObservationParams) Validate() error

type Permission

type Permission string

Permission names a capability-scoped sandbox permission.

type PrepareParams

type PrepareParams struct {
	ResolvedPlanDigest  publicschema.Digest      `json:"resolved_plan_digest"`
	CapabilityToken     string                   `json:"capability_token"`
	FixtureRefs         []publicschema.ObjectRef `json:"fixture_refs,omitempty"`
	ApprovedPermissions []Permission             `json:"approved_permissions"`
}

PrepareParams pins the approved plan and the subset of permissions offered to the driver. CapabilityToken is ephemeral and must never be persisted.

func (PrepareParams) Validate

func (params PrepareParams) Validate() error

type PrepareResult

type PrepareResult struct {
	AcceptedPermissions []Permission `json:"accepted_permissions"`
}

PrepareResult records the exact permission subset accepted by the driver.

type ProtocolError

type ProtocolError struct {
	Class   ErrorClass
	Message string
	Cause   error
}

ProtocolError is returned by codec and state-machine validation. Class is stable and suitable for a JSON-RPC ErrorData.Class value.

func (*ProtocolError) Error

func (err *ProtocolError) Error() string

func (*ProtocolError) Unwrap

func (err *ProtocolError) Unwrap() error

type RPCError

type RPCError struct {
	Code    int        `json:"code"`
	Message string     `json:"message"`
	Data    *ErrorData `json:"data"`
}

RPCError is the JSON-RPC error object.

func (RPCError) Validate

func (rpcError RPCError) Validate() error

Validate checks the stable class and the JSON-RPC error body.

type ResetParams

type ResetParams struct{}

type ResetResult

type ResetResult struct{}

type ShutdownParams

type ShutdownParams struct{}

type ShutdownResult

type ShutdownResult struct{}

type State

type State string

State is the serial v1 Driver RPC lifecycle state.

const (
	StateNew      State = "NEW"
	StateHello    State = "HELLO"
	StatePrepared State = "PREPARED"
	StateInvoking State = "INVOKING"
	StateShutdown State = "SHUTDOWN"
)

type TerminalStatus

type TerminalStatus string

TerminalStatus is emitted exactly once for an invocation.

const (
	TerminalCompleted TerminalStatus = "completed"
	TerminalCancelled TerminalStatus = "cancelled"
	TerminalErrored   TerminalStatus = "errored"
)

type VersionRange

type VersionRange struct {
	Minimum string `json:"minimum"`
	Maximum string `json:"maximum"`
}

VersionRange is the inclusive Driver RPC version range offered at hello.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL