protocol

package
v0.5.39-beta Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package protocol defines the versioned JSON-RPC protocol shared by Kodelet control planes and workspace-bound runners.

Index

Constants

View Source
const (
	// EnrollmentStartPath starts a runner device-enrollment flow.
	EnrollmentStartPath = "/api/runner/v1/enrollment/start"
	// EnrollmentPollPath polls a runner device-enrollment flow for approval.
	EnrollmentPollPath = "/api/runner/v1/enrollment/poll"
)
View Source
const (
	// DPoPHeader carries an RFC 9449 proof JWT.
	DPoPHeader = "DPoP"
	// DPoPAuthorizationScheme identifies a DPoP-bound access token.
	DPoPAuthorizationScheme = "DPoP"
	// DPoPProofType is the required typ protected-header value for a DPoP proof.
	DPoPProofType = "dpop+jwt"
	// RunnerAccessTokenPrefix distinguishes enrolled runner access tokens from other credentials.
	RunnerAccessTokenPrefix = "kltr_"
)
View Source
const (
	// Version is the initial runner application protocol version.
	Version = 1
	// JSONRPCVersion is the JSON-RPC wire version used by the runner protocol.
	JSONRPCVersion = "2.0"
	// Subprotocol is required during the WebSocket upgrade.
	Subprotocol = "kodelet.runner.v1.jsonrpc"
	// Endpoint is the control-plane WebSocket endpoint used by runners.
	Endpoint = "/api/runner/v1/connect"
)
View Source
const (
	MethodRunnerRegister          = "runner.register"
	MethodRunnerHeartbeat         = "runner.heartbeat"
	MethodRunnerManifestChanged   = "runner.manifestChanged"
	MethodRunnerGoodbye           = "runner.goodbye"
	MethodRunOpen                 = "run.open"
	MethodRunClose                = "run.close"
	MethodRunCancel               = "run.cancel"
	MethodRunEnvironmentError     = "run.environmentError"
	MethodCommandExecute          = "command.execute"
	MethodLifecycleDispatch       = "lifecycle.dispatch"
	MethodToolExecute             = "tool.execute"
	MethodToolUpdate              = "tool.update"
	MethodConversationFork        = "conversation.fork"
	MethodWorkspaceGitDiff        = "workspace.git.diff"
	MethodWorkspaceTerminalOpen   = "workspace.terminal.open"
	MethodWorkspaceTerminalRead   = "workspace.terminal.read"
	MethodWorkspaceTerminalInput  = "workspace.terminal.input"
	MethodWorkspaceTerminalResize = "workspace.terminal.resize"
	MethodUIInput                 = "ui.input"
	MethodUIConfirm               = "ui.confirm"
	MethodUISelect                = "ui.select"
	MethodUINotify                = "ui.notify"
	MethodUIWidgetSet             = "ui.widget.set"
	MethodUIWidgetFrame           = "ui.widget.frame"
	MethodUIWidgetRemove          = "ui.widget.remove"
	MethodUITranscriptAppend      = "ui.transcript.append"
	MethodUISurfaceOpen           = "ui.surface.open"
	MethodUISurfaceFrame          = "ui.surface.frame"
	MethodUISurfaceClose          = "ui.surface.close"
	MethodUISurfaceInput          = "ui.surface.input"
	MethodUISurfaceResize         = "ui.surface.resize"
	MethodOperationCancel         = "operation.cancel"
)
View Source
const (
	ErrorCodeParseError     = -32700
	ErrorCodeInvalidRequest = -32600
	ErrorCodeMethodNotFound = -32601
	ErrorCodeInvalidParams  = -32602
	ErrorCodeInternal       = -32603
	ErrorCodeUnavailable    = -32000
	ErrorCodeConflict       = -32001
	ErrorCodeStale          = -32002
	ErrorCodeBusy           = -32003
)
View Source
const (
	ErrorReasonRunnerNotFound = "runner_not_found"
	ErrorReasonRunNotActive   = "run_not_active"
	ErrorReasonResultTooLarge = "result_too_large"
)

Variables

View Source
var (
	// ErrPeerClosed is returned when an RPC operation targets a closed peer.
	ErrPeerClosed = errors.New("runner rpc peer is closed")
	// ErrPeerNotStarted is returned when an operation precedes Start.
	ErrPeerNotStarted = errors.New("runner rpc peer is not started")
)

Functions

func CredentialFingerprint

func CredentialFingerprint(publicKey ed25519.PublicKey) (string, error)

CredentialFingerprint returns the stable SHA-256 fingerprint for an Ed25519 public key.

func DPoPAccessTokenHash

func DPoPAccessTokenHash(accessToken string) (string, error)

DPoPAccessTokenHash returns the RFC 9449 ath value for an access token.

func DecodePublicKey

func DecodePublicKey(encoded string) (ed25519.PublicKey, error)

DecodePublicKey parses a canonical unpadded base64url Ed25519 public key.

func EncodePublicKey

func EncodePublicKey(publicKey ed25519.PublicKey) (string, error)

EncodePublicKey returns the canonical unpadded base64url representation of an Ed25519 public key.

func NewRunnerAccessToken

func NewRunnerAccessToken() (string, error)

NewRunnerAccessToken returns a cryptographically random opaque token suitable for DPoP binding.

func NormalizeDPoPHTU

func NormalizeDPoPHTU(raw string) (string, error)

NormalizeDPoPHTU returns the query- and fragment-free HTTP target URI used by RFC 9449. WebSocket ws/wss URLs are mapped to their HTTP handshake schemes.

func RequestIDFromContext

func RequestIDFromContext(ctx context.Context) string

RequestIDFromContext returns the wire request ID for an inbound RPC handler.

func SignDPoPProof

func SignDPoPProof(privateKey ed25519.PrivateKey, options DPoPProofOptions) (string, error)

SignDPoPProof creates an EdDSA-signed RFC 9449 proof JWT with an embedded public JWK.

func SupportsVersion

func SupportsVersion(versions []int, version int) bool

SupportsVersion reports whether a peer advertised a protocol version.

func ValidateRunnerAccessToken

func ValidateRunnerAccessToken(token string) error

ValidateRunnerAccessToken checks the canonical runner access-token representation.

Types

type AgentDescriptor

type AgentDescriptor struct {
	Provider           string `json:"provider"`
	Model              string `json:"model"`
	Profile            string `json:"profile,omitempty"`
	EnvironmentProfile string `json:"environmentProfile,omitempty"`
	RecipeName         string `json:"recipeName,omitempty"`
	InvokedBy          string `json:"invokedBy,omitempty"`
}

AgentDescriptor carries only provider-sensitive identifiers needed by runner resources.

type ClientCapabilities

type ClientCapabilities struct {
	InteractiveUI      bool `json:"interactiveUI"`
	PersistentSurfaces bool `json:"persistentSurfaces"`
}

ClientCapabilities describes the interactive client attached to a run.

type DPoPProofOptions

type DPoPProofOptions struct {
	Method      string
	TargetURL   string
	AccessToken string
	JTI         string
	IssuedAt    time.Time
	Nonce       string
}

DPoPProofOptions describes one RFC 9449 proof JWT.

type DPoPVerificationOptions

type DPoPVerificationOptions struct {
	Method      string
	TargetURL   string
	AccessToken string
	PublicKey   ed25519.PublicKey
	Now         time.Time
	MaxAge      time.Duration
	FutureSkew  time.Duration
}

DPoPVerificationOptions defines the request and credential binding expected by a resource server.

type EnrollmentPollRequest

type EnrollmentPollRequest struct {
	EnrollmentID string `json:"enrollmentId"`
	DeviceCode   string `json:"deviceCode"`
}

EnrollmentPollRequest identifies one pending device-enrollment flow.

func (EnrollmentPollRequest) Validate

func (r EnrollmentPollRequest) Validate() error

Validate checks the private polling identifiers returned by enrollment start.

type EnrollmentPollResponse

type EnrollmentPollResponse struct {
	Status       EnrollmentStatus `json:"status"`
	CredentialID string           `json:"credentialId,omitempty"`
	AccessToken  string           `json:"accessToken,omitempty"`
	TokenType    string           `json:"tokenType,omitempty"`
	Fingerprint  string           `json:"fingerprint,omitempty"`
	RunnerID     string           `json:"runnerId,omitempty"`
	RetryAfterMS int64            `json:"retryAfterMs,omitempty"`
}

EnrollmentPollResponse reports approval state and, once approved, the DPoP-bound credential.

type EnrollmentStartRequest

type EnrollmentStartRequest struct {
	ProtocolVersions []int     `json:"protocolVersions,omitempty"`
	PublicKey        string    `json:"publicKey"`
	Fingerprint      string    `json:"fingerprint"`
	Host             Host      `json:"host"`
	Workspace        Workspace `json:"workspace"`
	DisplayName      string    `json:"displayName,omitempty"`
	KodeletVersion   string    `json:"kodeletVersion,omitempty"`
}

EnrollmentStartRequest describes the runner and public key awaiting approval.

func (EnrollmentStartRequest) Validate

func (r EnrollmentStartRequest) Validate() error

Validate checks the enrollment identity and Ed25519 public-key binding.

type EnrollmentStartResponse

type EnrollmentStartResponse struct {
	EnrollmentID            string    `json:"enrollmentId"`
	DeviceCode              string    `json:"deviceCode"`
	UserCode                string    `json:"userCode"`
	VerificationURL         string    `json:"verificationUrl"`
	VerificationURLComplete string    `json:"verificationUrlComplete,omitempty"`
	ExpiresAt               time.Time `json:"expiresAt"`
	PollIntervalMS          int64     `json:"pollIntervalMs"`
}

EnrollmentStartResponse returns the device code and browser approval location.

type EnrollmentStatus

type EnrollmentStatus string

EnrollmentStatus is the current state of a device-enrollment flow.

const (
	EnrollmentStatusPending  EnrollmentStatus = "pending"
	EnrollmentStatusApproved EnrollmentStatus = "approved"
	EnrollmentStatusDenied   EnrollmentStatus = "denied"
	EnrollmentStatusExpired  EnrollmentStatus = "expired"
)

type EnvironmentErrorParams

type EnvironmentErrorParams struct {
	RunID   string `json:"runId"`
	Message string `json:"message"`
}

EnvironmentErrorParams reports a runner-side asynchronous run failure.

type GoodbyeParams

type GoodbyeParams struct {
	RunnerID   string `json:"runnerId"`
	Generation int64  `json:"generation"`
	Reason     string `json:"reason,omitempty"`
}

GoodbyeParams reports an intentional runner disconnect.

type HeartbeatParams

type HeartbeatParams struct {
	RunnerID       string      `json:"runnerId"`
	Generation     int64       `json:"generation"`
	State          RunnerState `json:"state"`
	ActiveRunID    string      `json:"activeRunId,omitempty"`
	ActiveRunIDs   []string    `json:"activeRunIds,omitempty"`
	ManifestDigest string      `json:"manifestDigest,omitempty"`
}

HeartbeatParams reports application health separately from WebSocket liveness.

func (HeartbeatParams) NormalizedActiveRunIDs

func (p HeartbeatParams) NormalizedActiveRunIDs() ([]string, error)

NormalizedActiveRunIDs returns the deterministic active-run set advertised by a heartbeat. ActiveRunID remains accepted for compatibility with singular-run runner clients.

func (HeartbeatParams) Validate

func (p HeartbeatParams) Validate() error

Validate checks heartbeat identity and application state fields.

type Host

type Host struct {
	InstanceID string `json:"instanceId"`
	Hostname   string `json:"hostname"`
	OS         string `json:"os"`
	Arch       string `json:"arch"`
	PID        int    `json:"pid,omitempty"`
}

Host describes one stable runner installation and its mutable display metadata.

type ManifestChangedParams

type ManifestChangedParams struct {
	RunnerID       string `json:"runnerId"`
	Generation     int64  `json:"generation"`
	ManifestDigest string `json:"manifestDigest"`
}

ManifestChangedParams reports an idle-manifest digest transition.

type Message

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

Message is the small JSON-native envelope used for requests, responses, and notifications. Runner request identifiers are strings with an origin-specific prefix.

func DecodeMessage

func DecodeMessage(payload []byte) (Message, error)

DecodeMessage decodes and validates one complete WebSocket text frame.

func (Message) Validate

func (m Message) Validate() error

Validate checks the JSON-RPC envelope shape used by this first-party protocol.

type NotificationHandler

type NotificationHandler interface {
	HandleNotification(ctx context.Context, method string, params json.RawMessage)
}

NotificationHandler handles notifications received from the remote peer.

type NotificationHandlerFunc

type NotificationHandlerFunc func(context.Context, string, json.RawMessage)

NotificationHandlerFunc adapts a function to NotificationHandler.

func (NotificationHandlerFunc) HandleNotification

func (f NotificationHandlerFunc) HandleNotification(ctx context.Context, method string, params json.RawMessage)

type OperationCancelParams

type OperationCancelParams struct {
	RequestID string `json:"requestId"`
}

OperationCancelParams cancels one in-flight JSON-RPC request by its wire ID.

type Peer

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

Peer owns one WebSocket reader, one writer, bounded outbound queues, and symmetric RPC correlation.

func NewPeer

func NewPeer(conn *websocket.Conn, config PeerConfig) (*Peer, error)

NewPeer creates a dormant peer. Start must be called after handlers have been fully wired.

func (*Peer) Call

func (p *Peer) Call(ctx context.Context, method string, params any, result any) error

Call sends a request and waits for its correlated response.

func (*Peer) CallTracked

func (p *Peer) CallTracked(ctx context.Context, method string, params any, result any, onRequestID func(string)) error

CallTracked sends a request and synchronously exposes its wire ID before enqueueing it.

func (*Peer) Close

func (p *Peer) Close() error

Close immediately terminates the peer and unblocks all pending operations.

func (*Peer) Done

func (p *Peer) Done() <-chan struct{}

Done closes after the transport and all in-flight handlers terminate.

func (*Peer) Err

func (p *Peer) Err() error

Err returns the terminal connection error after Done closes.

func (*Peer) Notify

func (p *Peer) Notify(ctx context.Context, method string, params any) error

Notify sends a normal-priority notification.

func (*Peer) NotifyUpdate

func (p *Peer) NotifyUpdate(method string, params any) error

NotifyUpdate sends a replaceable low-priority notification. When the bounded queue is full, the oldest pending update is discarded in favor of this one.

func (*Peer) Shutdown

func (p *Peer) Shutdown(ctx context.Context, code int, reason string) error

Shutdown sends a WebSocket close frame, then terminates the peer.

func (*Peer) Start

func (p *Peer) Start(parent context.Context) error

Start launches the peer's reader, writer, and ping loops.

func (*Peer) TransportDone

func (p *Peer) TransportDone() <-chan struct{}

TransportDone closes as soon as the WebSocket transport terminates.

type PeerConfig

type PeerConfig struct {
	RequestPrefix                string
	Handler                      RequestHandler
	Notifications                NotificationHandler
	ControlQueueSize             int
	UpdateQueueSize              int
	WriteWait                    time.Duration
	ShutdownWait                 time.Duration
	PongWait                     time.Duration
	PingPeriod                   time.Duration
	ReadLimit                    int64
	WriteLimit                   int64
	MaxConcurrentRequests        int
	MaxConcurrentControlRequests int
	MaxConcurrentNotifications   int
}

PeerConfig configures one symmetric JSON-RPC WebSocket peer.

type RPCError

type RPCError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    any    `json:"data,omitempty"`
}

RPCError is a JSON-RPC error object.

func (*RPCError) Error

func (e *RPCError) Error() string

func (*RPCError) Reason

func (e *RPCError) Reason() string

Reason returns the stable machine-readable reason from an RPC error.

type RPCErrorData

type RPCErrorData struct {
	Reason string `json:"reason,omitempty"`
}

RPCErrorData carries stable machine-readable error details.

type RegisterParams

type RegisterParams struct {
	ProtocolVersions []int              `json:"protocolVersions"`
	RunnerID         string             `json:"runnerId,omitempty"`
	DisplayName      string             `json:"displayName,omitempty"`
	Host             Host               `json:"host"`
	Workspace        Workspace          `json:"workspace"`
	Capabilities     RunnerCapabilities `json:"capabilities,omitempty"`
	KodeletVersion   string             `json:"kodeletVersion"`
	ManifestDigest   string             `json:"manifestDigest,omitempty"`
}

RegisterParams is the first request sent by a runner connection.

func (RegisterParams) Validate

func (p RegisterParams) Validate() error

Validate checks registration identity and version negotiation fields.

type RegisterResult

type RegisterResult struct {
	RunnerID            string `json:"runnerId"`
	ProtocolVersion     int    `json:"protocolVersion"`
	ConnectionID        string `json:"connectionId"`
	Generation          int64  `json:"generation"`
	HeartbeatIntervalMS int64  `json:"heartbeatIntervalMs"`
}

RegisterResult establishes the stable runner ID and live connection generation.

type RequestHandler

type RequestHandler interface {
	HandleRequest(ctx context.Context, method string, params json.RawMessage) (any, *RPCError)
}

RequestHandler handles requests received from the remote peer.

type RequestHandlerFunc

type RequestHandlerFunc func(context.Context, string, json.RawMessage) (any, *RPCError)

RequestHandlerFunc adapts a function to RequestHandler.

func (RequestHandlerFunc) HandleRequest

func (f RequestHandlerFunc) HandleRequest(ctx context.Context, method string, params json.RawMessage) (any, *RPCError)

type RunCancelParams

type RunCancelParams struct {
	RunID  string `json:"runId"`
	Reason string `json:"reason,omitempty"`
}

RunCancelParams cancels active runner operations for one run.

type RunCloseParams

type RunCloseParams struct {
	RunID string `json:"runId"`
}

RunCloseParams releases a pinned run environment.

type RunOpenParams

type RunOpenParams struct {
	RunID              string             `json:"runId"`
	ConversationID     string             `json:"conversationId"`
	Agent              AgentDescriptor    `json:"agent"`
	ClientCapabilities ClientCapabilities `json:"clientCapabilities"`
	ReservedToolNames  []string           `json:"reservedToolNames"`
}

RunOpenParams asks a runner to pin one environment snapshot.

func (RunOpenParams) Validate

func (p RunOpenParams) Validate() error

type RunStatus

type RunStatus string

RunStatus is the durable-shape state machine shared by remote environments and the control plane.

const (
	RunStatusOpening   RunStatus = "opening"
	RunStatusRunning   RunStatus = "running"
	RunStatusSucceeded RunStatus = "succeeded"
	RunStatusFailed    RunStatus = "failed"
	RunStatusCanceled  RunStatus = "canceled"
	RunStatusLost      RunStatus = "lost"
)

type RunnerCapabilities

type RunnerCapabilities struct {
	ConcurrentRuns    bool `json:"concurrentRuns,omitempty"`
	WorkspaceGitDiff  bool `json:"workspaceGitDiff,omitempty"`
	WorkspaceTerminal bool `json:"workspaceTerminal,omitempty"`
}

RunnerCapabilities declares optional behavior supported by this runner process.

type RunnerState

type RunnerState string

RunnerState is the application-level availability reported by heartbeats.

const (
	RunnerStateIdle     RunnerState = "idle"
	RunnerStateRunning  RunnerState = "running"
	RunnerStateStopping RunnerState = "stopping"
	RunnerStateError    RunnerState = "error"
)

type VerifiedDPoPProof

type VerifiedDPoPProof struct {
	JTI           string
	IssuedAt      time.Time
	JWKThumbprint string
}

VerifiedDPoPProof contains replay and key-binding information from a verified proof.

func VerifyDPoPProof

func VerifyDPoPProof(proof string, options DPoPVerificationOptions) (VerifiedDPoPProof, error)

VerifyDPoPProof verifies an RFC 9449 proof and its request, token, time, and key bindings. Replay detection remains the resource server's responsibility using the returned JTI.

type Workspace

type Workspace struct {
	Path string `json:"path"`
	Name string `json:"name"`
}

Workspace describes the one canonical workspace bound to a runner process.

type WorkspaceGitDiffParams

type WorkspaceGitDiffParams struct{}

WorkspaceGitDiffParams asks a runner to inspect its registered workspace.

type WorkspaceGitDiffResult

type WorkspaceGitDiffResult struct {
	CWD       string `json:"cwd"`
	Diff      string `json:"diff"`
	HasDiff   bool   `json:"hasDiff"`
	GitRoot   string `json:"gitRoot,omitempty"`
	ExitCode  int    `json:"exitCode"`
	Truncated bool   `json:"truncated,omitempty"`
}

WorkspaceGitDiffResult is a bounded git diff snapshot from a runner workspace.

type WorkspaceTerminalInputParams

type WorkspaceTerminalInputParams struct {
	SessionID string `json:"sessionId"`
	Data      []byte `json:"data"`
}

WorkspaceTerminalInputParams writes bytes to a runner terminal session.

type WorkspaceTerminalOpenParams

type WorkspaceTerminalOpenParams struct {
	Rows int `json:"rows,omitempty"`
	Cols int `json:"cols,omitempty"`
}

WorkspaceTerminalOpenParams opens or reattaches to the runner workspace terminal.

type WorkspaceTerminalOpenResult

type WorkspaceTerminalOpenResult struct {
	SessionID    string `json:"sessionId"`
	CWD          string `json:"cwd"`
	Name         string `json:"name"`
	Git          bool   `json:"git"`
	PID          int    `json:"pid,omitempty"`
	ReplayCursor uint64 `json:"replayCursor"`
	WriteCursor  uint64 `json:"writeCursor"`
}

WorkspaceTerminalOpenResult describes one persistent runner terminal session.

type WorkspaceTerminalReadParams

type WorkspaceTerminalReadParams struct {
	SessionID string `json:"sessionId"`
	Cursor    uint64 `json:"cursor"`
	MaxBytes  int    `json:"maxBytes,omitempty"`
	WaitMS    int    `json:"waitMs,omitempty"`
}

WorkspaceTerminalReadParams long-polls terminal output from one absolute cursor.

type WorkspaceTerminalReadResult

type WorkspaceTerminalReadResult struct {
	Data       []byte `json:"data,omitempty"`
	NextCursor uint64 `json:"nextCursor"`
	Truncated  bool   `json:"truncated,omitempty"`
	Exited     bool   `json:"exited,omitempty"`
	ExitCode   int    `json:"exitCode,omitempty"`
}

WorkspaceTerminalReadResult returns the next bounded terminal output chunk.

type WorkspaceTerminalResizeParams

type WorkspaceTerminalResizeParams struct {
	SessionID string `json:"sessionId"`
	Rows      int    `json:"rows"`
	Cols      int    `json:"cols"`
}

WorkspaceTerminalResizeParams resizes a runner terminal session.

Directories

Path Synopsis
Package payload defines runner application payloads that depend on Kodelet's model, tool, slash-command, and extension types.
Package payload defines runner application payloads that depend on Kodelet's model, tool, slash-command, and extension types.

Jump to

Keyboard shortcuts

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