Documentation
¶
Overview ¶
Package rpc is Orb's embedding protocol (DECISIONS.md P1, P10): upstream pi's strict-LF, bidirectional JSONL RPC mode served over any byte stream. Frames are a kernel surface and stay byte-compatible with upstream. The package is headless and reads no process state: hosts supply the streams and any termination source (signals, worker shutdown) through Options.
Index ¶
- func ReadFrames(reader io.Reader, lines chan<- []byte, readErrors chan<- error)
- func Serve(ctx context.Context, host SessionHost, options Options) int
- type Command
- type ExtensionUI
- func (ui *ExtensionUI) Confirm(ctx context.Context, title, message string, timeoutMS *int64) (bool, error)
- func (ui *ExtensionUI) Editor(ctx context.Context, title string, prefill *string) (*string, error)
- func (ui *ExtensionUI) HandleResponse(response ExtensionUIResponse)
- func (ui *ExtensionUI) Input(ctx context.Context, title string, placeholder *string, timeoutMS *int64) (*string, error)
- func (ui *ExtensionUI) Notify(message, notifyType string) error
- func (ui *ExtensionUI) Select(ctx context.Context, title string, options []string, timeoutMS *int64) (*string, error)
- func (ui *ExtensionUI) SetEditorText(text string) error
- func (ui *ExtensionUI) SetStatus(key string, text *string) error
- func (ui *ExtensionUI) SetTitle(title string) error
- func (ui *ExtensionUI) SetWidget(key string, lines []string, placement string) error
- type ExtensionUIRequest
- type ExtensionUIResponse
- type FrameWriter
- type Options
- type Response
- type RuntimeHost
- func (host *RuntimeHost) Dispose()
- func (host *RuntimeHost) Fork(entryID string, atEntry bool) (string, bool, error)
- func (host *RuntimeHost) NewSession(parentSession string) (bool, error)
- func (host *RuntimeHost) Session() *agent.SessionRuntime
- func (host *RuntimeHost) SetRebindSession(rebind func(*agent.SessionRuntime) error)
- func (host *RuntimeHost) SwitchSession(sessionPath string) (bool, error)
- type SessionHost
- type SessionState
- type SlashCommand
- type SourceInfo
- type ThinkingLevels
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ReadFrames ¶
ReadFrames splits reader into LF-terminated frames the way upstream's strict JSONL reader does (one trailing CR stripped, final unterminated frame kept), sending copies to lines, then closes lines and reports the read error (nil at EOF) on readErrors.
func Serve ¶
func Serve(ctx context.Context, host SessionHost, options Options) int
Serve runs upstream's strict-LF, bidirectional JSONL protocol until Input ends, the context is cancelled, or the host requests termination, and returns the process-style exit code upstream's RPC mode would exit with.
Types ¶
type Command ¶
type Command struct {
ID string `json:"id,omitempty"`
Type string `json:"type"`
Message string `json:"message,omitempty"`
Images []*ai.ImageContent `json:"images,omitempty"`
StreamingBehavior string `json:"streamingBehavior,omitempty"`
ParentSession string `json:"parentSession,omitempty"`
Provider string `json:"provider,omitempty"`
ModelID string `json:"modelId,omitempty"`
Level string `json:"level,omitempty"`
Mode string `json:"mode,omitempty"`
CustomInstructions string `json:"customInstructions,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
Command string `json:"command,omitempty"`
ExcludeFromContext *bool `json:"excludeFromContext,omitempty"`
OutputPath string `json:"outputPath,omitempty"`
SessionPath string `json:"sessionPath,omitempty"`
EntryID string `json:"entryId,omitempty"`
Since *string `json:"since,omitempty"`
Name string `json:"name,omitempty"`
HasID bool `json:"-"`
}
type ExtensionUI ¶
type ExtensionUI struct {
// contains filtered or unexported fields
}
ExtensionUI implements the RPC dialog sub-protocol.
func (*ExtensionUI) HandleResponse ¶
func (ui *ExtensionUI) HandleResponse(response ExtensionUIResponse)
func (*ExtensionUI) Notify ¶
func (ui *ExtensionUI) Notify(message, notifyType string) error
func (*ExtensionUI) SetEditorText ¶
func (ui *ExtensionUI) SetEditorText(text string) error
func (*ExtensionUI) SetTitle ¶
func (ui *ExtensionUI) SetTitle(title string) error
type ExtensionUIRequest ¶
type ExtensionUIRequest struct {
Type string `json:"type"`
ID string `json:"id"`
Method string `json:"method"`
Title string `json:"title,omitempty"`
Options []string `json:"options,omitempty"`
Timeout *int64 `json:"timeout,omitempty"`
Message string `json:"message,omitempty"`
Placeholder *string `json:"placeholder,omitempty"`
Prefill *string `json:"prefill,omitempty"`
NotifyType string `json:"notifyType,omitempty"`
StatusKey string `json:"statusKey,omitempty"`
StatusText *string `json:"statusText,omitempty"`
WidgetKey string `json:"widgetKey,omitempty"`
WidgetLines *[]string `json:"widgetLines,omitempty"`
WidgetPlacement string `json:"widgetPlacement,omitempty"`
Text string `json:"text,omitempty"`
}
func (ExtensionUIRequest) MarshalJSON ¶
func (request ExtensionUIRequest) MarshalJSON() ([]byte, error)
type ExtensionUIResponse ¶
type FrameWriter ¶
type FrameWriter struct {
// contains filtered or unexported fields
}
FrameWriter serializes JSONL frames onto one writer from a single goroutine, so session events, command responses and extension UI requests never interleave. The first write error stops output; Close reports it. Print mode's JSON output shares it, being the same event stream (json-event.ts).
func NewFrameWriter ¶
func NewFrameWriter(writer io.Writer) *FrameWriter
NewFrameWriter starts the writer goroutine; Close stops it.
func (*FrameWriter) Abort ¶ added in v0.14.0
func (output *FrameWriter) Abort()
Abort releases queued producers and Close without waiting for a stalled writer. An in-flight io.Writer.Write cannot be interrupted; it may finish after Abort returns, but no caller must wait for it during forced shutdown.
func (*FrameWriter) Close ¶
func (output *FrameWriter) Close() error
Close stops accepting frames, drains output unless aborted, and returns the first write or encoding error. It is safe to call concurrently.
func (*FrameWriter) WriteEvent ¶
func (output *FrameWriter) WriteEvent(event any)
WriteEvent encodes a session event in the stdout JSON/RPC shape (message_update delta-only) and queues it. Events arriving after Close started are dropped.
func (*FrameWriter) WriteFrame ¶
func (output *FrameWriter) WriteFrame(value []byte)
WriteFrame queues one encoded frame, which it takes over; the terminating LF is added.
type Options ¶
type Options struct {
// Input carries command frames; its end shuts the server down.
Input io.Reader
// Output receives response, event and extension UI frames.
Output io.Writer
// Diagnostics receives transport and startup errors; nil discards them.
Diagnostics io.Writer
// Commands lists the slash commands get_commands reports.
Commands func() []SlashCommand
// Terminate delivers a host shutdown request (the CLI maps SIGTERM and
// SIGHUP here) carrying the exit code Serve returns after disposing the
// session and flushing Output.
Terminate <-chan int
}
Options wire a server to its host. Input and Output are required.
type Response ¶
type Response struct {
ID string `json:"id,omitempty"`
Type string `json:"type"`
Command string `json:"command"`
Success bool `json:"success"`
Data any `json:"data,omitempty"`
Error string `json:"error,omitempty"`
HasID bool `json:"-"`
HasData bool `json:"-"`
}
Response is the common response envelope emitted by RPC mode. Field order follows upstream's object construction order because transcript bytes are a public wire format.
func (Response) MarshalJSON ¶
type RuntimeHost ¶
type RuntimeHost struct {
// contains filtered or unexported fields
}
RuntimeHost is the SessionHost over an agent.AgentSessionRuntime: session replacements run through the runtime and the server rebinds after each one.
func NewRuntimeHost ¶
func NewRuntimeHost(ctx context.Context, runtime *agent.AgentSessionRuntime, deferInitialBind bool) (*RuntimeHost, error)
NewRuntimeHost builds the host. Unless deferInitialBind is set it binds the session's extensions at construction (emitting the initial session_start). Set deferInitialBind when Serve will bind extensions itself after installing the RPC extension UI, so session_start fires once, with a live ctx.ui rather than the headless noop (the session must also be created with DeferExtensionStart so construction does not fire session_start first).
func (*RuntimeHost) Dispose ¶
func (host *RuntimeHost) Dispose()
func (*RuntimeHost) NewSession ¶
func (host *RuntimeHost) NewSession(parentSession string) (bool, error)
func (*RuntimeHost) Session ¶
func (host *RuntimeHost) Session() *agent.SessionRuntime
func (*RuntimeHost) SetRebindSession ¶
func (host *RuntimeHost) SetRebindSession(rebind func(*agent.SessionRuntime) error)
func (*RuntimeHost) SwitchSession ¶
func (host *RuntimeHost) SwitchSession(sessionPath string) (bool, error)
type SessionHost ¶
type SessionHost interface {
Session() *agent.SessionRuntime
NewSession(parentSession string) (cancelled bool, err error)
SwitchSession(sessionPath string) (cancelled bool, err error)
Fork(entryID string, atEntry bool) (text string, cancelled bool, err error)
Dispose()
}
SessionHost owns the session a server drives and performs the session replacements RPC commands request.
type SessionState ¶
type SessionState struct {
Model *ai.Model `json:"model,omitempty"`
ThinkingLevel ai.ModelThinkingLevel `json:"thinkingLevel"`
IsStreaming bool `json:"isStreaming"`
IsCompacting bool `json:"isCompacting"`
SteeringMode string `json:"steeringMode"`
FollowUpMode string `json:"followUpMode"`
SessionFile string `json:"sessionFile,omitempty"`
SessionID string `json:"sessionId"`
SessionName *string `json:"sessionName,omitempty"`
AutoCompactionEnabled bool `json:"autoCompactionEnabled"`
MessageCount int `json:"messageCount"`
PendingMessageCount int `json:"pendingMessageCount"`
}
type SlashCommand ¶
type SlashCommand struct {
Name string `json:"name"`
Description *string `json:"description,omitempty"`
Source string `json:"source"`
SourceInfo SourceInfo `json:"sourceInfo"`
}
func SlashCommands ¶
func SlashCommands(runtime *agent.SessionRuntime) []SlashCommand
SlashCommands reports runtime's commands in the get_commands wire shape.
type SourceInfo ¶
type ThinkingLevels ¶
type ThinkingLevels struct {
Levels []ai.ModelThinkingLevel `json:"levels"`
}