host

package
v0.4.13 Latest Latest
Warning

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

Go to latest
Published: Aug 10, 2026 License: MIT Imports: 32 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 added in v0.4.13

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 added in v0.4.13

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 added in v0.4.13

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 added in v0.4.13

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 added in v0.4.13

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 added in v0.4.13

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 added in v0.4.13

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 added in v0.4.13

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 codingagent.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 added in v0.4.13

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 added in v0.4.13

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

AgentSessionStats is the consumed subset of upstream SessionStats.

type AgentSessionStorage added in v0.4.13

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 added in v0.4.13

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 added in v0.4.13

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    agent.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 added in v0.4.13

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 added in v0.4.13

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
	// ProjectTrusted mirrors DiscoveryOptions.ProjectTrusted for consumers that
	// gate project-scoped resources on the same trust decision.
	ProjectTrusted  bool
	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) Retryable

func (err *ProviderInvokeError) Retryable() bool

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 added in v0.4.13

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 added in v0.4.13

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