Help us shape the future of Go! Take the 2026 Go Developer Survey

host

package
v0.19.12 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2026 License: MIT Imports: 36 Imported by: 0

Documentation

Overview

Package host implements orb's original out-of-process JavaScript extension host protocol and lifecycle manager. It has no mirrored upstream package.

Index

Constants

View Source
const (
	SessionEventGeneric          = "event"
	SessionEventMessagesSnapshot = "messages_snapshot"
	SessionEventMessageAppended  = "message_appended"
	SessionEventMessageUpdated   = "message_updated"
	SessionEventStats            = "stats"
)

Wire kinds of agent_session_event frames, one per AgentSessionCallbacks sink. They mirror the SDK transport's event contract (sdk/internal/services.mjs): onEvent / onMessagesSnapshot / onMessageAppended / onMessageUpdated / onStats.

View Source
const (
	ProtocolName    = "orb-extension-host"
	ProtocolVersion = 1
	MaxFrameSize    = 4 << 20
)

Variables

View Source
var (
	ErrNotRunning = errors.New("extension host is not running")
	ErrRestarting = errors.New("extension host is restarting")
)
View Source
var (
	ErrFrameTooLarge   = errors.New("extension host: frame exceeds 4 MiB")
	ErrIncompleteFrame = errors.New("extension host: unterminated JSONL frame")
)

Functions

func Discover

func Discover(options DiscoveryOptions) []string

Discover returns extension entry points in upstream load order with the first spelling of an absolute path winning deduplication.

func HelloCapabilities

func HelloCapabilities() []string

HelloCapabilities returns the capability list orb advertises in the handshake response, in wire order. Callers get a copy.

Types

type AgentInfo

type AgentInfo struct {
	Name     string `json:"name"`
	Version  string `json:"version"`
	CWD      string `json:"cwd"`
	AgentDir string `json:"agentDir"`
}

type AgentSessionCallbacks

type AgentSessionCallbacks struct {
	// OnEvent mirrors a raw upstream-shaped AgentSessionEvent; it drives
	// session.subscribe listeners.
	OnEvent func(payload any)
	// OnMessagesSnapshot replaces the session.messages mirror wholesale. Use
	// the appended/updated deltas below when volume allows: 16-way fan-outs
	// stream against the 4 MiB frame cap.
	OnMessagesSnapshot func(messages any)
	// OnMessageAppended appends one message to the mirror.
	OnMessageAppended func(message any)
	// OnMessageUpdated replaces the mirror entry at index (delta updates).
	OnMessageUpdated func(index int, message any)
	// OnStats updates the getSessionStats() mirror.
	OnStats func(stats AgentSessionStats)
}

AgentSessionCallbacks stream a session's activity back to the SDK's local mirrors. The dispatch layer constructs them (all funcs non-nil); every invocation becomes an agent_session_event frame carrying the handle, a per-handle monotonic seq, the kind, and the payload — chunked when it would exceed the 4 MiB frame cap. They map 1:1 onto the SDK transport's event sinks: the messages mirror is how the plugin observes history (it derives usage from the stats mirror, and model fallback/resolution from the create result), so implementations must keep these mirrors live DURING Prompt, not only at settle — the plugin throttles history off subscribe ticks.

type AgentSessionCreateRequest

type AgentSessionCreateRequest struct {
	ExtensionID string
	Options     AgentSessionOptions
	// ResolveModelRuntime resolves Options.ModelRuntime to the live registry
	// view it references ("context" = the requesting extension's
	// ctx.modelRegistry; otherwise a model_runtime_v1 handle minted by this
	// host). nil when the SDK passed no modelRuntime.
	ResolveModelRuntime func() (extensions.ModelRegistry, error)
	// ExecuteTool round-trips a customTools invocation into the host JS
	// process (execute_session_tool request): the transport retained the live
	// tool closures under this session's handle and runs prepareArguments
	// before execute. onUpdate, if non-nil, receives streamed tool_update
	// partials; the result is the raw upstream AgentToolResult JSON. The
	// implementation must schema-validate params against the tool's JSON
	// Schema (D14) before calling — passing either the validated value or its
	// order-preserving raw JSON encoding (upstream hands the parsed JS object
	// through with member order intact) — and honor `terminate: true` in the
	// result by ending the turn.
	ExecuteTool func(ctx context.Context, toolName, toolCallID string, params any, onUpdate func(json.RawMessage)) (json.RawMessage, error)
}

AgentSessionCreateRequest carries one agent_session_create invocation.

type AgentSessionCreateResult

type AgentSessionCreateResult struct {
	ModelFallbackMessage string    `json:"modelFallbackMessage,omitempty"`
	Model                *ai.Model `json:"model,omitempty"`
}

AgentSessionCreateResult mirrors the non-session fields of the SDK's CreateAgentSessionResult.

type AgentSessionHandle

type AgentSessionHandle interface {
	// Prompt resolves when the turn settles. Provider quota/limit failures
	// must NOT surface as an error: they land in the message mirror as a final
	// assistant message with stopReason "error" and the provider's verbatim
	// errorMessage (the plugin classifies limits by that wording).
	Prompt(ctx context.Context, text string, options json.RawMessage) error
	// Messages returns the full message mirror as a JSON array of
	// upstream-shaped AgentMessage values.
	Messages(ctx context.Context) (json.RawMessage, error)
	Abort(ctx context.Context) error
	SessionStats(ctx context.Context) (AgentSessionStats, error)
	SetActiveToolsByName(ctx context.Context, names []string) error
	// AppendSessionInfo is best-effort session naming
	// (SessionManager.appendSessionInfo forwarded post-create).
	AppendSessionInfo(ctx context.Context, name string) error
	// Dispose releases the session. The dispatch layer calls it at most once
	// per handle and drops callback events emitted afterwards.
	Dispose(ctx context.Context) error
}

AgentSessionHandle is one live child session behind a Go-minted string handle. Every method maps 1:1 to an agent_session_v1 request — except Messages and SessionStats, which have no wire dispatch: the SDK reads both from the event mirrors (messages_snapshot/appended/updated, stats). ctx is cancelled when the SDK aborts that request (service_cancel).

type AgentSessionOptions

type AgentSessionOptions struct {
	// CWD is the per-session working directory (fan-out runs pass git
	// worktrees here).
	CWD      string `json:"cwd,omitempty"`
	AgentDir string `json:"agentDir,omitempty"`
	// Model may be an off-catalog synthesized entry (the plugin's model-spec
	// fallback spreads a sibling model with a new id); implementations must
	// route by its fields and not require catalog membership. Model "tiers"
	// never cross this wire: upstream CreateAgentSessionOptions has no tier
	// field — extensions resolve tiers client-side (model-tiers.json) into a
	// concrete Model before calling createAgentSession, which the F13
	// model-routing scenario gates end to end.
	Model         *ai.Model             `json:"model,omitempty"`
	ThinkingLevel ai.ModelThinkingLevel `json:"thinkingLevel,omitempty"`
	ScopedModels  json.RawMessage       `json:"scopedModels,omitempty"`
	// ModelRuntime references the model_runtime_v1 handle whose catalog/auth
	// view the session must resolve models against.
	ModelRuntime *ModelRuntimeRef `json:"modelRuntime,omitempty"`
	// NoTools disables tools wholesale: "all" or "builtin".
	NoTools string `json:"noTools,omitempty"`
	// Tools is a name allowlist over the session's tool set; ExcludeTools is a
	// name denylist applied after it and always wins.
	Tools        []string `json:"tools,omitempty"`
	ExcludeTools []string `json:"excludeTools,omitempty"`
	// CustomTools reference host-JS tool closures executed via
	// AgentSessionCreateRequest.ExecuteTool — except Builtin markers, which the
	// implementation serves with Go-native tools bound to CWD. There is no
	// separate systemTools field: upstream CreateAgentSessionOptions has none —
	// callers (e.g. pi-dynamic-workflows' per-agent store tools) fold system
	// tools into customTools before createAgentSession, so they arrive here
	// already folded.
	CustomTools []AgentSessionTool `json:"customTools,omitempty"`
	// Session carries the SessionManager thin-handle fields; Settings and
	// ResourceLoader the SettingsManager / DefaultResourceLoader ones.
	Session        *AgentSessionStorage        `json:"session,omitempty"`
	Settings       *AgentSessionSettings       `json:"settings,omitempty"`
	ResourceLoader *AgentSessionResourceLoader `json:"resourceLoader,omitempty"`
	// SessionStartEvent is an upstream-shaped session_start payload to replay
	// into the child, when the SDK forwards one.
	SessionStartEvent json.RawMessage `json:"sessionStartEvent,omitempty"`
}

AgentSessionOptions mirrors the SDK's CreateAgentSessionOptions across the wire, field for field.

type AgentSessionResourceLoader

type AgentSessionResourceLoader struct {
	ExtensionID  string `json:"extensionId,omitempty"`
	CWD          string `json:"cwd,omitempty"`
	AgentDir     string `json:"agentDir,omitempty"`
	NoExtensions bool   `json:"noExtensions,omitempty"`
}

AgentSessionResourceLoader is the DefaultResourceLoader handle. NoExtensions true is the plugin's structural anti-recursion guarantee: the child loads no extensions while skills/prompts/AGENTS.md context still load.

type AgentSessionService

type AgentSessionService interface {
	// CreateSession starts a child agent session. Callbacks the implementation
	// invokes before one of the handle's methods returns are delivered to the
	// SDK in seq order before that operation's terminal result; callbacks
	// invoked after the method returns race the result and must not carry
	// turn-scoped events.
	CreateSession(ctx context.Context, request AgentSessionCreateRequest, callbacks AgentSessionCallbacks) (AgentSessionHandle, AgentSessionCreateResult, error)
	// ReloadResources backs DefaultResourceLoader.reload() (sdk_v1
	// sdk_resource_reload): reload or prewarm the resource set (skills,
	// prompts, AGENTS.md context — never extensions when NoExtensions) that
	// the next CreateSession for the same cwd/agentDir observes.
	ReloadResources(ctx context.Context, request AgentSessionResourceLoader) error
}

AgentSessionService is the runtime seam behind the agent_session_v1 capability (and sdk_v1's resource reload). The protocol layer owns handle minting, per-handle monotonic event seq, frame-cap chunking, request cancellation, and error envelopes; the implementation owns the child-session runtime — backed by agent.NewAgentSession with extension loading disabled (runner lane). Install it with Manager.SetAgentSessionService; the default is a stub whose CreateSession returns a precise not-yet-wired ServiceError so the protocol layer stays testable before the runtime lands.

type AgentSessionSettings

type AgentSessionSettings struct {
	CWD      string `json:"cwd,omitempty"`
	AgentDir string `json:"agentDir,omitempty"`
}

AgentSessionSettings is the inert SettingsManager handle: the implementation applies real settings (default model, thinking level, blockImages) from these roots when creating the session.

type AgentSessionStats

type AgentSessionStats struct {
	Tokens AgentSessionTokens `json:"tokens"`
	Cost   float64            `json:"cost"`
}

AgentSessionStats is the consumed subset of upstream SessionStats.

type AgentSessionStorage

type AgentSessionStorage struct {
	Persisted  bool   `json:"persisted"`
	SessionDir string `json:"sessionDir,omitempty"`
	CWD        string `json:"cwd,omitempty"`
	// SessionInfoNames are appendSessionInfo names queued on the JS handle
	// before the session existed.
	SessionInfoNames []string `json:"sessionInfoNames,omitempty"`
}

AgentSessionStorage carries the SessionManager thin handle. Persisted false means SessionManager.inMemory(); when true, SessionDir is the real, already-created session directory the SDK computed from the handshake's sessionsRoot.

type AgentSessionTokens

type AgentSessionTokens struct {
	Input      int64 `json:"input"`
	Output     int64 `json:"output"`
	CacheRead  int64 `json:"cacheRead"`
	CacheWrite int64 `json:"cacheWrite"`
	Total      int64 `json:"total"`
}

type AgentSessionTool

type AgentSessionTool struct {
	// Builtin names one of the SDK's createCodingTools markers ("read",
	// "bash", "edit", "write"): served natively, never called back into JS.
	// PromptSnippet/PromptGuidelines may ride along carrying upstream
	// createCodingTools' system-prompt contribution (bash only upstream); the
	// remaining callback fields are unused for builtin entries.
	Builtin string `json:"builtin,omitempty"`

	Name             string                   `json:"name,omitempty"`
	Label            string                   `json:"label,omitempty"`
	Description      string                   `json:"description,omitempty"`
	PromptSnippet    string                   `json:"promptSnippet,omitempty"`
	PromptGuidelines []string                 `json:"promptGuidelines,omitempty"`
	Parameters       json.RawMessage          `json:"parameters,omitempty"` // JSON Schema (D14)
	ExecutionMode    engine.ToolExecutionMode `json:"executionMode,omitempty"`
}

AgentSessionTool is one customTools entry.

type DiscoveryOptions

type DiscoveryOptions struct {
	CWD                         string
	AgentDir                    string
	ProjectTrusted              bool
	NoDiscovery                 bool
	ConfiguredPaths             []string
	ProjectConfiguredPaths      []string
	ResolvedPackagePaths        []string
	ProjectResolvedPackagePaths []string
	ExplicitPaths               []string
}

DiscoveryOptions contains local paths after settings and package resolution. Package resolution remains the caller's responsibility.

type LoadError

type LoadError struct {
	Path  string `json:"path"`
	Error string `json:"error"`
}

type LoadResult

type LoadResult struct {
	Paths       []string
	Errors      []LoadError
	Diagnostics []extensions.Diagnostic
	Runtime     *Runtime
}

type Manager

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

func NewManager

func NewManager(options Options) *Manager

func (*Manager) Close

func (manager *Manager) Close() error

func (*Manager) RegisterInto

func (manager *Manager) RegisterInto(ctx context.Context, registry *extensions.Registry, paths []string) LoadResult

func (*Manager) Reload

func (manager *Manager) Reload(ctx context.Context) error

func (*Manager) RestartCount

func (manager *Manager) RestartCount() int64

func (*Manager) Runtime

func (manager *Manager) Runtime() *Runtime

func (*Manager) SetAgentSessionService

func (manager *Manager) SetAgentSessionService(service AgentSessionService)

SetAgentSessionService installs the runtime behind agent_session_v1 and sdk_v1 resource reloads. nil restores the not-yet-wired stub. Sessions created earlier keep the service they were created with.

type ModelRuntimeRef

type ModelRuntimeRef struct {
	Handle      string `json:"handle"`
	ExtensionID string `json:"extensionId,omitempty"`
}

ModelRuntimeRef names a model_runtime_v1 handle. The reserved handle "context" is the requesting extension's own ctx.modelRegistry view, in which case ExtensionID identifies the extension.

type Options

type Options struct {
	AgentDir        string
	CWD             string
	Version         string
	Runtime         *Runtime
	OrbExecutable   string
	RequestTimeout  time.Duration
	ShutdownTimeout time.Duration
	MaxRestarts     int
	BackoffBase     time.Duration
	BackoffMax      time.Duration
	Stderr          io.Writer
	OnDiagnostic    func(extensions.Diagnostic)
}

type ProviderInvokeError

type ProviderInvokeError struct {
	ExtensionID string
	ProviderID  string
	Method      string
	CanRetry    bool
	Cause       error
}

ProviderInvokeError distinguishes extension failures from transport failures. A retryable error means the process generation disappeared or was replaced; callers may retry against the next generation without rebuilding the registry.

func (*ProviderInvokeError) Error

func (err *ProviderInvokeError) Error() string

func (*ProviderInvokeError) Unwrap

func (err *ProviderInvokeError) Unwrap() error

type Runtime

type Runtime struct {
	Name    string
	Version string
	Path    string
	Args    []string
}

func DiscoverRuntime

func DiscoverRuntime(ctx context.Context) (Runtime, error)

type RuntimeUnavailableError

type RuntimeUnavailableError struct {
	NodeVersion string
}

func (*RuntimeUnavailableError) Diagnostic

func (err *RuntimeUnavailableError) Diagnostic() extensions.Diagnostic

func (*RuntimeUnavailableError) Error

type ServiceError

type ServiceError struct {
	Code    string
	Message string
}

ServiceError is a structured failure from a protocol service (sdk_v1, agent_session_v1, model_runtime_v1). Code and Message cross the wire verbatim as the {code,message} error envelope of the request's response; service errors never tear the channel.

func (*ServiceError) Error

func (err *ServiceError) Error() string

type UIDialogCancellationError

type UIDialogCancellationError struct {
	Reason UIDialogCancellationReason
}

func (*UIDialogCancellationError) Error

func (err *UIDialogCancellationError) Error() string

type UIDialogCancellationReason

type UIDialogCancellationReason string
const UIDialogCancellationHostRestarted UIDialogCancellationReason = "host_restarted"

Jump to

Keyboard shortcuts

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