inprocess

package
v1.0.4 Latest Latest
Warning

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

Go to latest
Published: Mar 12, 2026 License: MIT Imports: 29 Imported by: 0

Documentation

Overview

Package inprocess provides an in-process plugin router that dispatches tool calls, storage operations, and prompt requests via direct Go function calls instead of QUIC network round-trips. It implements the Sender interface used by StdioTransport and the StorageClient interface used by plugins.

Package inprocess — tunnel_token provides one-time registration tokens for the web-gate tunnel system. When a machine starts `orchestra serve --web-gate`, it generates a token containing machine metadata. The user copies this token to the web app to register the tunnel.

Package inprocess — webgate adds a WebSocket JSON-RPC 2.0 gateway to orchestra serve, allowing browser clients to call MCP tools directly via the in-process Router. This turns each machine running `orchestra serve` into a remotely accessible tunnel.

Unlike the QUIC bridge's wsbridge (which connects to an orchestrator over QUIC), the WebGateServer uses the Router directly — no network hop.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClaimTunnel added in v1.0.4

func ClaimTunnel(ctx context.Context, cloudURL, nonce string) (tunnelID, connectionToken, teamID, authToken string, err error)

ClaimTunnel polls the cloud server's claim endpoint until the user registers the tunnel in the web app. Once registered, it returns the tunnel ID and connection token needed to establish the reverse tunnel.

The nonce is the secret from the registration token that the CLI generated. The cloud server stores a nonce→credentials mapping when the user pastes the token in the web app.

func ClientTLSConfigForBridge

func ClientTLSConfigForBridge(certsDir string) (*tls.Config, error)

ClientTLSConfigForBridge returns a TLS config suitable for the orchestra host to connect to child plugin QUIC servers. This is a convenience wrapper around the SDK's ClientTLSConfig with the correct ALPN protocol.

func FormatTokenDisplay added in v1.0.4

func FormatTokenDisplay(raw string, token *TunnelToken) string

FormatTokenDisplay returns a terminal-friendly display of the tunnel token for the user to copy to the web app. Uses \r\n line endings and plain ASCII so it renders correctly whether the terminal is in raw mode or not.

func TunnelLog added in v1.0.4

func TunnelLog(color int, format string, args ...any)

func VerifyAPIKeyHash added in v1.0.4

func VerifyAPIKeyHash(apiKey, hash string) bool

VerifyAPIKeyHash checks if a plaintext API key matches the hash stored in a token.

Types

type ExternalPlugin

type ExternalPlugin struct {
	ID         string
	ProvidesAI []string
	ToolDefs   []*pluginv1.ToolDefinition
	PromptDefs []*pluginv1.PromptDefinition
	Client     Sender
}

ExternalPlugin represents a QUIC-connected plugin that runs as a separate process (e.g. engine-rag written in Rust, or third-party plugins). The router forwards requests to it via its Send method.

func (*ExternalPlugin) Send

Send forwards a request to the external plugin via its QUIC client.

type QUICBridge

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

QUICBridge is a QUIC listener that child plugin processes connect to for storage access and cross-plugin tool calls. The router proxies all requests through its in-process handlers.

type ReverseTunnelClient added in v1.0.4

type ReverseTunnelClient struct {
	OnConnect func(ctx context.Context) // called after each successful connect
	// contains filtered or unexported fields
}

ReverseTunnelClient maintains a persistent outbound WebSocket connection from the local machine to the cloud server. It receives relay envelopes containing JSON-RPC requests from browser sessions, dispatches them through the in-process Router, and sends responses back.

func NewReverseTunnelClient added in v1.0.4

func NewReverseTunnelClient(cloudURL, tunnelID, connectionToken string, router *Router) *ReverseTunnelClient

NewReverseTunnelClient creates a new reverse tunnel client.

func (*ReverseTunnelClient) ReconnectLoop added in v1.0.4

func (rt *ReverseTunnelClient) ReconnectLoop(ctx context.Context)

ReconnectLoop connects to the cloud server and automatically reconnects with exponential backoff on failure. Blocks until ctx is cancelled.

type Router

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

Router dispatches PluginRequests to in-process tool handlers, storage handlers, and prompt handlers. It replaces the QUIC-based orchestrator router for local IDE use. External plugins (e.g. engine-rag) are supported via ExternalPlugin entries that forward requests over QUIC.

Router implements the Sender interface:

Send(ctx, *PluginRequest) (*PluginResponse, error)

This means it can be passed directly to StdioTransport and also used as the clientAdapter for plugins that need cross-plugin storage calls.

func NewRouter

func NewRouter() *Router

NewRouter creates a new in-process Router.

func (*Router) GetStreamHandler added in v1.0.2

func (r *Router) GetStreamHandler(toolName string) (plugin.StreamingToolHandler, bool)

GetStreamHandler returns the streaming tool handler for the given tool name.

func (*Router) ListToolNames

func (r *Router) ListToolNames() []string

ListToolNames returns a list of all registered tool names (for logging).

func (*Router) ListenAndServeQUIC

func (r *Router) ListenAndServeQUIC(ctx context.Context, addr string, certsDir string) (string, error)

ListenAndServeQUIC starts a QUIC listener using mTLS certificates from the given certsDir. Child plugins connect to this address (passed as --orchestrator-addr) to make storage and cross-plugin RPC calls.

Returns the actual bound address (e.g. "127.0.0.1:56789") which should be passed to spawnPlugin when starting child processes.

func (*Router) RegisterExternal

func (r *Router) RegisterExternal(ep *ExternalPlugin)

RegisterExternal adds an external QUIC-connected plugin to the router. External plugins override in-process handlers for same-named tools, allowing installable plugins to supersede bundled core tool definitions.

func (*Router) RegisterPlugin

func (r *Router) RegisterPlugin(ep *plugin.ExportedPlugin)

RegisterPlugin registers all tools, streaming tools, and prompts from an ExportedPlugin. If the plugin's manifest declares ProvidesAI, tools are indexed under the AI routing table instead of the generic tool table.

func (*Router) Send

Send implements the Sender interface. It dispatches a PluginRequest to the appropriate in-process handler based on the request type.

func (*Router) SetStorageHandler

func (r *Router) SetStorageHandler(h plugin.StorageHandler)

SetStorageHandler sets the storage backend (typically storage-markdown).

type Sender

type Sender interface {
	Send(ctx context.Context, req *pluginv1.PluginRequest) (*pluginv1.PluginResponse, error)
}

Sender abstracts the QUIC client for external plugins.

type TCPSender added in v1.0.4

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

TCPSender implements the Sender interface by forwarding Protobuf requests to an existing orchestra instance over a persistent TCP connection. This is used by proxy mode: when a new `orchestra serve` is spawned and finds a healthy instance, it creates a TCPSender connected to that instance and passes it to StdioTransport, bridging stdin/stdout ↔ TCP.

If the connection drops (e.g. orchestrator restart), Send automatically reconnects and retries the request.

func NewTCPSender added in v1.0.4

func NewTCPSender(addr string) (*TCPSender, error)

NewTCPSender connects to an existing orchestra instance's TCP server.

func (*TCPSender) Close added in v1.0.4

func (s *TCPSender) Close() error

Close closes the TCP connection.

func (*TCPSender) Send added in v1.0.4

Send forwards a PluginRequest to the remote instance and reads the response. It implements the Sender interface used by StdioTransport.

On connection errors (broken pipe, connection reset, EOF), it automatically reconnects and retries the request once.

type TCPServer

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

TCPServer listens for desktop app connections (Swift, Windows, Linux) and proxy connections from other orchestra serve instances. Uses the same length-delimited Protobuf protocol as the orchestrator's TCP bridge. Each TCP connection is persistent — multiple requests can be sent over a single connection (the connection stays open until the client disconnects).

func NewTCPServer

func NewTCPServer(addr string, router *Router) *TCPServer

NewTCPServer creates a TCP server bound to the given address.

func (*TCPServer) Addr

func (s *TCPServer) Addr() string

Addr returns the actual listening address. Only valid after ListenAndServe.

func (*TCPServer) ListenAndServe

func (s *TCPServer) ListenAndServe(ctx context.Context) error

ListenAndServe starts the TCP listener and processes connections until the context is cancelled. Each connection receives one PluginRequest and gets one PluginResponse back, using the SDK's length-delimited Protobuf framing.

type TunnelToken added in v1.0.4

type TunnelToken struct {
	// Machine identification
	Hostname string `json:"hostname"`
	OS       string `json:"os"`
	Arch     string `json:"arch"`

	// Network
	LocalIP     string `json:"local_ip"`
	GateAddress string `json:"gate_address"`
	CloudURL    string `json:"cloud_url,omitempty"` // cloud server URL for reverse tunnel

	// Security
	APIKeyHash string `json:"api_key_hash,omitempty"` // SHA-256 of the API key (empty if no auth)
	Nonce      string `json:"nonce"`                  // random nonce for uniqueness

	// Metadata
	ToolCount int    `json:"tool_count"`
	CreatedAt string `json:"created_at"`          // ISO 8601
	Workspace string `json:"workspace,omitempty"` // absolute workspace path (for multi-workspace tunnels)
}

TunnelToken contains the machine metadata embedded in a registration token. The web app decodes this to verify the tunnel and store connection info.

func DecodeToken added in v1.0.4

func DecodeToken(raw string) (*TunnelToken, error)

DecodeToken decodes a raw base64url token string into a TunnelToken. This is used by the web backend to inspect the token contents.

type TunnelTokenManager added in v1.0.4

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

TunnelTokenManager handles token generation, storage, and one-time verification.

func NewTunnelTokenManager added in v1.0.4

func NewTunnelTokenManager() *TunnelTokenManager

NewTunnelTokenManager creates a new token manager.

func (*TunnelTokenManager) GenerateToken added in v1.0.4

func (m *TunnelTokenManager) GenerateToken(gateAddress, apiKey, cloudURL, workspace string, toolCount int) (string, error)

GenerateToken creates a new registration token with machine metadata. Only one token is active at a time — generating a new one invalidates the previous.

func (*TunnelTokenManager) HasPendingToken added in v1.0.4

func (m *TunnelTokenManager) HasPendingToken() bool

HasPendingToken returns true if there is an unconsumed registration token.

func (*TunnelTokenManager) RevokeToken added in v1.0.4

func (m *TunnelTokenManager) RevokeToken()

RevokeToken invalidates any pending token without consuming it.

func (*TunnelTokenManager) VerifyToken added in v1.0.4

func (m *TunnelTokenManager) VerifyToken(rawToken string) (*TunnelToken, error)

VerifyToken checks if the provided token matches the current pending token. On success, the token is consumed (one-time use) and the decoded token is returned. Returns an error if no token is pending, or the token doesn't match.

type WebGateServer added in v1.0.4

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

WebGateServer exposes the in-process Router over WebSocket for remote browser clients. Each WebSocket connection is a persistent session that can send multiple JSON-RPC 2.0 requests over the same connection.

func NewWebGateServer added in v1.0.4

func NewWebGateServer(router *Router, apiKey, cloudURL, workspace string, corsOrigins []string) *WebGateServer

NewWebGateServer creates a WebGateServer. If apiKey is empty, authentication is disabled. corsOrigins controls which browser origins can connect (empty = allow all).

func (*WebGateServer) Addr added in v1.0.4

func (wg *WebGateServer) Addr() string

Addr returns the actual listening address. Only valid after ListenAndServe.

func (*WebGateServer) GenerateRegistrationToken added in v1.0.4

func (wg *WebGateServer) GenerateRegistrationToken() (string, *TunnelToken, error)

GenerateRegistrationToken creates a new tunnel registration token using the current gate address and tool count. Returns the raw base64 token string.

func (*WebGateServer) ListenAndServe added in v1.0.4

func (wg *WebGateServer) ListenAndServe(ctx context.Context, addr string) error

ListenAndServe starts the HTTP server with WebSocket upgrade support. It blocks until ctx is cancelled or a fatal error occurs.

func (*WebGateServer) StartEventPoller added in v1.0.4

func (wg *WebGateServer) StartEventPoller(ctx context.Context)

StartEventPoller starts a background goroutine that polls drain_session_events every 200ms and pushes any pending events to all connected WebSocket clients as server-initiated notifications. This enables real-time streaming of tool cards and text in the web copilot.

func (*WebGateServer) StartPermissionPoller added in v1.0.4

func (wg *WebGateServer) StartPermissionPoller(ctx context.Context)

StartPermissionPoller starts a background goroutine that polls get_pending_permission every second and pushes any pending requests to all connected WebSocket clients as server-initiated notifications. This bridges the gap where bridge-claude (external QUIC plugin) captures permission events from Claude CLI processes but has no way to push them to the browser.

func (*WebGateServer) TokenManager added in v1.0.4

func (wg *WebGateServer) TokenManager() *TunnelTokenManager

TokenManager returns the tunnel token manager for external use (e.g. serve.go generates a token after startup and displays it in the terminal).

Jump to

Keyboard shortcuts

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