server

package
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

Documentation

Overview

Package server serves a durable.Runtime over host-defined wire protocols.

Protocol is the extension point. Implement it to own HTTP/WebSocket routes, stream framing, and HITL resume. ACP is the native option (NewACPProtocol); more protocols can be mounted on the same Server:

srv := server.NewServer(rt, cat, server.NewACPProtocol(nil), myProtocol{})
_ = srv.ServeHTTP(ctx, addr)

RunTurn pumps Runtime.Prompt/Resume/Subscribe through Protocol.OnStreamEvent and OnStreamClosed. Map wire credentials into durable.AuthContext on the work item. Runtime, harness, VFS, and Temporal do not import this package.

Index

Constants

View Source
const (
	HeaderAcpConnectionID = "Acp-Connection-Id"
	HeaderAcpSessionID    = "Acp-Session-Id"

	// CookieAcpAffinity sticks a client to the same backend for one connection.
	CookieAcpAffinity = "acp_affinity"
)

Header names for the ACP Streamable HTTP / WebSocket transport (RFD).

Variables

View Source
var (
	ErrInvalidRequest         = errors.New("invalid request")
	ErrMethodNotFound         = errors.New("method not found")
	ErrInternal               = errors.New("internal server error")
	ErrAgentNotFound          = durable.ErrAgentNotFound
	ErrSessionNotFound        = durable.ErrSessionNotFound
	ErrAuthenticationRequired = tacklrsecurity.ErrAuthenticationRequired
	ErrAuthenticationFailed   = tacklrsecurity.ErrAuthenticationFailed
	ErrAuthorizationDenied    = tacklrsecurity.ErrAuthorizationDenied
)

Wire-facing sentinels. Session/agent/auth groups are the owning package's sentinels (same pointer) so errors.Is is one check.

View Source
var ErrNetworkSecurityPolicyRequired = errors.New("server: configure security or explicitly allow anonymous network access")

ErrNetworkSecurityPolicyRequired prevents accidental anonymous listeners.

View Source
var ErrRequestCancelled = errors.New("request cancelled")

ErrRequestCancelled is returned when a request is aborted via session/cancel or context cancellation.

Functions

func ElicitationResultToSelectionPayload

func ElicitationResultToSelectionPayload(raw json.RawMessage, opts []interrupt.UserChoice) (action string, resolution []byte, err error)

ElicitationResultToSelectionPayload maps an accept response to the harness interrupt resolution payload. Returns action and optional selection JSON.

func IsClientError

func IsClientError(err error) bool

func JSONRPCErrorCode

func JSONRPCErrorCode(err error) int

JSONRPCErrorCode maps err to a JSON-RPC 2.0 error code.

func ParseToolPermissionFromInterruptData

func ParseToolPermissionFromInterruptData(data []byte) (interruptID string, perm interrupt.ToolPermissionInterrupt, err error)

ParseToolPermissionFromInterruptData extracts a tool permission interrupt from yield data.

func ParseUserSelectionFromInterruptData

func ParseUserSelectionFromInterruptData(data []byte) (interruptID string, usi interrupt.UserSelectionInterrupt, err error)

ParseUserSelectionFromInterruptData extracts options from StreamEventInterrupt Data payload shape {"interruptId":"...","data":<serialized UserSelectionInterrupt>}.

func PermissionToACPParams

func PermissionToACPParams(sessionID, toolCallID string, perm interrupt.ToolPermissionInterrupt) map[string]any

PermissionToACPParams builds session/request_permission params.

func PublicError

func PublicError(err error) error

PublicError returns a wire-safe error: client errors pass through unchanged; all other errors become ErrInternal so internal details are not leaked.

func RequestPermissionResultToPayload

func RequestPermissionResultToPayload(raw json.RawMessage) (resolution []byte, cancelled bool, err error)

RequestPermissionResultToPayload maps a client permission response to the harness resolution payload. cancelled yields a non-nil err suitable for ending the turn.

func RunTurn added in v0.2.0

func RunTurn(
	ctx context.Context,
	env ProtocolEnv,
	proto Protocol,
	threadID string,
	reqID json.RawMessage,
	prompt PromptOrResume,
) error

RunTurn pumps Runtime.Prompt or Resume, then Subscribe, through proto's stream policy.

func SelectionToElicitationParams

func SelectionToElicitationParams(sessionID, toolCallID, question string, opts []interrupt.UserChoice) (map[string]any, error)

SelectionToElicitationParams builds form-mode elicitation/create params from a user-selection interrupt.

Types

type ACPAuthMethod added in v0.2.0

type ACPAuthMethod struct {
	ID          string
	Name        string
	Description string
	Scheme      string
}

ACPAuthMethod presents one host security scheme through the ACP v1 agent authentication flow. Scheme is the protocol-neutral Authenticator identifier.

type ClientBridge

type ClientBridge struct {

	// Caps is protected by mu; use GetCaps/SetCaps from concurrent handlers.
	Caps ClientCapabilities
	// contains filtered or unexported fields
}

ClientBridge sends JSON-RPC requests to the Client and demuxes responses by id. Safe for concurrent Call from tool/turn goroutines; one bridge per connection.

func NewClientBridge

func NewClientBridge(w MessageWriter) *ClientBridge

NewClientBridge creates a bridge that writes requests through w.

func (*ClientBridge) Call

func (b *ClientBridge) Call(ctx context.Context, method string, params any) (json.RawMessage, error)

Call sends a JSON-RPC request and waits for the matching response or ctx cancel.

func (*ClientBridge) GetCaps

func (b *ClientBridge) GetCaps() ClientCapabilities

GetCaps returns a snapshot of client capabilities (safe for concurrent use).

func (*ClientBridge) MarkInitialized added in v0.2.0

func (b *ClientBridge) MarkInitialized()

MarkInitialized records that initialize completed on this connection.

func (*ClientBridge) SetCaps

func (b *ClientBridge) SetCaps(c ClientCapabilities)

SetCaps stores client capabilities (safe for concurrent use).

func (*ClientBridge) TryCompleteResponse

func (b *ClientBridge) TryCompleteResponse(body []byte) bool

TryCompleteResponse returns true if body is a JSON-RPC response that completed a waiter.

func (*ClientBridge) WaitInitialized added in v0.2.0

func (b *ClientBridge) WaitInitialized(ctx context.Context) error

WaitInitialized blocks until initialize has run or ctx is done. If initialize already completed, that wins even when ctx is also ready.

type ClientCapabilities

type ClientCapabilities struct {
	ElicitationForm bool
	ElicitationURL  bool
	VFSTokenRefresh bool
}

ClientCapabilities captures client features from initialize.

func ParseClientCapabilities

func ParseClientCapabilities(params json.RawMessage) ClientCapabilities

ParseClientCapabilities extracts elicitation mode support and Tacklr VFS token refresh from initialize params.

type ConfigOption

type ConfigOption struct {
	ID           string              `json:"id"`
	Name         string              `json:"name"`
	Description  string              `json:"description,omitempty"`
	Category     string              `json:"category"`
	Type         string              `json:"type"`
	CurrentValue string              `json:"currentValue"`
	Options      []ConfigOptionValue `json:"options"`
}

ConfigOption describes a selectable session configuration option returned by session/new and session/load.

type ConfigOptionValue

type ConfigOptionValue struct {
	Value       string `json:"value"`
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
}

ConfigOptionValue is one choice within a select-type ConfigOption.

type Conn

type Conn struct {
	Writer   MessageWriter
	RPC      *ClientBridge
	Security *tacklrsecurity.Context
	// contains filtered or unexported fields
}

Conn is one client connection (WebSocket session, or a logical HTTP request scope).

type Connection

type Connection struct {
	ID     string
	Bridge *ClientBridge
	Writer MessageWriter
	// contains filtered or unexported fields
}

Connection is one client transport connection (WebSocket or Streamable HTTP). Harness sessions live on durable.Runtime; this is ephemeral wire state only.

func (*Connection) Context

func (c *Connection) Context() context.Context

Context is cancelled when the connection is removed or shut down.

type ConnectionRegistry

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

ConnectionRegistry tracks active ACP connections by Acp-Connection-Id.

func NewConnectionRegistry

func NewConnectionRegistry() *ConnectionRegistry

NewConnectionRegistry returns an empty registry.

func (*ConnectionRegistry) Create

func (r *ConnectionRegistry) Create(bridge *ClientBridge, writer MessageWriter) *Connection

Create registers a new connection with a generated id and cancellable context. bridge/writer may be filled in after Create (WebSocket accept path).

func (*ConnectionRegistry) Get

func (r *ConnectionRegistry) Get(id string) *Connection

Get returns the connection for id, or nil.

func (*ConnectionRegistry) Remove

func (r *ConnectionRegistry) Remove(id string)

Remove deletes the connection and cancels its context. Safe if missing or r is nil.

type ElicitationResult

type ElicitationResult struct {
	Action  string         `json:"action"`
	Content map[string]any `json:"content"`
}

ElicitationResult is the Client response to elicitation/create.

type HTTPAttemptExtractor added in v0.2.0

type HTTPAttemptExtractor func(*http.Request) (tacklrsecurity.Attempt, bool)

HTTPAttemptExtractor translates transport credential evidence into the protocol-neutral security model. It is an edge adapter, not part of the core.

type HTTPRoute

type HTTPRoute struct {
	Method               string // e.g. "POST"
	Pattern              string // e.g. "/acp"
	AllowUnauthenticated bool
	Handler              func(env ProtocolEnv, w http.ResponseWriter, r *http.Request)
}

HTTPRoute is one HTTP endpoint owned by a Protocol.

type InterruptEventEnvelope

type InterruptEventEnvelope struct {
	InterruptId string          `json:"interruptId"`
	Type        string          `json:"type"`
	Data        json.RawMessage `json:"data"`
}

InterruptEventEnvelope is the harness StreamEventInterrupt Data shape.

func ParseInterruptEnvelope

func ParseInterruptEnvelope(data []byte) (InterruptEventEnvelope, error)

ParseInterruptEnvelope extracts interrupt id, type, and raw data from a yield event.

type MemoryWireStore

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

MemoryWireStore is an in-process ProtocolWireStore.

func NewMemoryWireStore

func NewMemoryWireStore() *MemoryWireStore

NewMemoryWireStore returns an empty in-memory wire store.

func (*MemoryWireStore) Delete

func (s *MemoryWireStore) Delete(_ context.Context, sessionID string) error

func (*MemoryWireStore) Get

func (s *MemoryWireStore) Get(_ context.Context, sessionID string) ([]byte, error)

func (*MemoryWireStore) Put

func (s *MemoryWireStore) Put(_ context.Context, sessionID string, payload []byte) error

type MessageWriter

type MessageWriter interface {
	WriteResult(id json.RawMessage, result any) error
	// WriteError writes a failure. Implementations should use PublicError /
	// JSONRPCErrorCode so internal details are not leaked on the wire.
	WriteError(id json.RawMessage, err error) error
	WriteFrame(data []byte) error
}

MessageWriter is the sink a Protocol uses for results and streamed frames. Each protocol supplies an implementation for its wire (JSON-RPC, custom HTTP, WebSocket).

type PostgresWireStore

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

PostgresWireStore implements ProtocolWireStore against Postgres. Call Setup once per database. Shares a *pgx.Conn with a brain store when desired; the table is separate from harness session checkpoints.

func NewPostgresWireStore

func NewPostgresWireStore(conn *pgx.Conn, protocolKey string) *PostgresWireStore

NewPostgresWireStore wraps an existing pgx connection. protocolKey labels rows (e.g. "acp"); empty defaults to "acp".

func (*PostgresWireStore) Delete

func (s *PostgresWireStore) Delete(ctx context.Context, sessionID string) error

func (*PostgresWireStore) Get

func (s *PostgresWireStore) Get(ctx context.Context, sessionID string) ([]byte, error)

func (*PostgresWireStore) Put

func (s *PostgresWireStore) Put(ctx context.Context, sessionID string, payload []byte) error

func (*PostgresWireStore) Setup added in v0.2.0

func (s *PostgresWireStore) Setup(ctx context.Context) error

Setup creates public.protocol_wire_session (idempotent).

type PromptOrResume added in v0.2.0

type PromptOrResume struct {
	Prompt durable.Prompt
	Resume *durable.Resume
	After  durable.Seq
}

PromptOrResume is one protocol turn against Runtime.

type Protocol

type Protocol interface {
	// HandleInbound decodes one connection-oriented body (WebSocket or unary HTTP).
	// HTTP-route-only protocols may return nil.
	HandleInbound(ctx context.Context, env ProtocolEnv, body []byte) error
	HTTPRoutes() []HTTPRoute

	OnStreamEvent(ctx context.Context, env ProtocolEnv, threadID string, ev tacklr.StreamEvent, reqID json.RawMessage) StreamControl
	OnStreamClosed(ctx context.Context, env ProtocolEnv, threadID string, reqID json.RawMessage, cancelled bool) error
}

Protocol is the host extension point for streaming and delivery over durable.Runtime.

ACP is the native implementation (NewACPProtocol). Hosts implement Protocol to define their own wire: HTTP/WebSocket routes, frame encoding, and HITL resume. The kernel does not import protocol types. Map wire auth into durable.AuthContext on Prompt/Resume; call RunTurn to pump Runtime.Subscribe through OnStreamEvent.

func NewACPProtocol

func NewACPProtocol(wire ProtocolWireStore) Protocol

NewACPProtocol returns the native ACP Protocol. Nil wire uses an in-memory store.

func NewACPProtocolWithAuth added in v0.2.0

func NewACPProtocolWithAuth(wire ProtocolWireStore, methods []ACPAuthMethod, logout bool) Protocol

NewACPProtocolWithAuth configures the ACP v1 presentation for a generic host security service. It does not implement credential verification itself.

type ProtocolEnv

type ProtocolEnv struct {
	Runtime durable.Runtime
	Catalog durable.Catalog
	Conn    *Conn
	// Security is protocol-neutral. Implementations map wire credentials into
	// this service and store the resulting Context on Conn.
	Security *tacklrsecurity.Service
	// Connections is optional connection tracking (ACP Streamable HTTP uses it).
	// Custom protocols may leave it unused.
	Connections *ConnectionRegistry
}

ProtocolEnv is the domain + connection context passed into protocol handlers.

type ProtocolWireStore

type ProtocolWireStore interface {
	Put(ctx context.Context, sessionID string, payload []byte) error
	Get(ctx context.Context, sessionID string) ([]byte, error)
	Delete(ctx context.Context, sessionID string) error
}

ProtocolWireStore persists protocol-owned session envelopes (not harness checkpoints). Payload is opaque JSON defined by each protocol. May share a database connection with other Tacklr stores without sharing schema.

type RequestPermissionResult

type RequestPermissionResult struct {
	Outcome struct {
		Outcome  string `json:"outcome"`
		OptionID string `json:"optionId,omitempty"`
	} `json:"outcome"`
}

RequestPermissionResult is the Client response to session/request_permission.

type Server

type Server struct {
	Runtime   durable.Runtime
	Catalog   durable.Catalog
	Protocols []Protocol
	// Connections tracks ACP Streamable HTTP / WebSocket connections.
	// Custom protocols may ignore it.
	Connections *ConnectionRegistry
	// Security is protocol-neutral authentication and authorization supplied by the host.
	Security *tacklrsecurity.Service
	// HTTPAttempt translates request credentials at the HTTP transport edge.
	HTTPAttempt HTTPAttemptExtractor
	// contains filtered or unexported fields
}

Server serves a durable.Runtime over HTTP, with WebSocket when the request upgrades. Protocols is the ordered list of wire implementations (ACP and/or host protocols).

func NewServer

func NewServer(rt durable.Runtime, cat durable.Catalog, protocols ...Protocol) *Server

NewServer wraps a Runtime and one or more Protocols. ACP is NewACPProtocol; pass additional implementations to mount their HTTPRoutes on the same mux.

func (*Server) AllowAnonymousNetwork added in v0.2.0

func (s *Server) AllowAnonymousNetwork() *Server

AllowAnonymousNetwork explicitly enables unauthenticated network serving. It is intended for local development and trusted private environments.

func (*Server) HTTPMux

func (s *Server) HTTPMux() *http.ServeMux

HTTPMux mounts every Protocol's HTTP routes. Used by ServeHTTP and tests.

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(ctx context.Context, addr string) error

ServeHTTP starts an HTTP server mounting all protocol routes.

func (*Server) WithSecurity added in v0.2.0

func (s *Server) WithSecurity(service *tacklrsecurity.Service, extract HTTPAttemptExtractor) *Server

WithSecurity installs host authentication and optional HTTP credential extraction. Protocol-native flows such as ACP authenticate can use service without an extractor.

type StreamControl

type StreamControl struct {
	Frames   [][]byte
	Resume   map[string][]byte
	Finished bool
	Err      error
}

StreamControl is the protocol's decision after observing one harness event.

Jump to

Keyboard shortcuts

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