eventpipe

package
v1.0.3 Latest Latest
Warning

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

Go to latest
Published: Jun 21, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package eventpipe implements a Reasonix-inspired event-sourcing pipeline: discriminated-union typed events → pure-function reducer projections → composable sink middleware chain → JSONL event log.

It lives alongside the old event.Event struct in internal/event; consumers can migrate event by event.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ByType

func ByType(types ...string) func(Event) bool

ByType returns a predicate that matches the given type strings. Usage: Filter(sink, ByType("model.delta", "model.final"))

func MarshalEvent

func MarshalEvent(ev Event) ([]byte, error)

MarshalEvent serializes any Event to JSON. The top-level {"type","meta","body"} envelope makes it self-describing for log/replay.

func SkipType

func SkipType(types ...string) func(Event) bool

SkipType returns a predicate that excludes the given type strings.

Types

type ApprovalRequestEvent

type ApprovalRequestEvent struct {
	AskID   string `json:"askId"`
	Tool    string `json:"tool"`
	Subject string `json:"subject"`
	// contains filtered or unexported fields
}

func NewApprovalRequestEvent

func NewApprovalRequestEvent(turn int, id int, askID, tool, subject string) ApprovalRequestEvent

func (ApprovalRequestEvent) Meta

func (e ApprovalRequestEvent) Meta() Meta

func (ApprovalRequestEvent) Type

func (e ApprovalRequestEvent) Type() string

type AskOption

type AskOption struct {
	Label       string `json:"label"`
	Description string `json:"description,omitempty"`
}

type AskQuestion

type AskQuestion struct {
	ID      string      `json:"id"`
	Header  string      `json:"header"`
	Prompt  string      `json:"prompt"`
	Options []AskOption `json:"options"`
	Multi   bool        `json:"multi"`
}

type AskRequestEvent

type AskRequestEvent struct {
	AskID     string        `json:"askId"`
	Questions []AskQuestion `json:"questions"`
	// contains filtered or unexported fields
}

func NewAskRequestEvent

func NewAskRequestEvent(turn int, id int, askID string, questions []AskQuestion) AskRequestEvent

func (AskRequestEvent) Meta

func (e AskRequestEvent) Meta() Meta

func (AskRequestEvent) Type

func (e AskRequestEvent) Type() string

type BudgetBlockedEvent

type BudgetBlockedEvent struct {
	SpentUSD float64 `json:"spentUsd"`
	CapUSD   float64 `json:"capUsd"`
	// contains filtered or unexported fields
}

func NewBudgetBlockedEvent

func NewBudgetBlockedEvent(turn int, id int, spent, cap float64) BudgetBlockedEvent

func (BudgetBlockedEvent) Meta

func (e BudgetBlockedEvent) Meta() Meta

func (BudgetBlockedEvent) Type

func (e BudgetBlockedEvent) Type() string

type BudgetView

type BudgetView struct {
	SpentUSD         float64 `json:"spentUsd"`
	CapUSD           float64 `json:"capUsd,omitempty"`
	PromptTokens     int     `json:"promptTokens"`
	CompletionTokens int     `json:"completionTokens"`
	CacheHitTokens   int     `json:"cacheHitTokens"`
	CacheMissTokens  int     `json:"cacheMissTokens"`
	Warned           bool    `json:"warned"`
	Blocked          bool    `json:"blocked"`
}

func EmptyBudget

func EmptyBudget(capUSD float64) BudgetView

type BudgetWarningEvent

type BudgetWarningEvent struct {
	SpentUSD float64 `json:"spentUsd"`
	CapUSD   float64 `json:"capUsd"`
	// contains filtered or unexported fields
}

func NewBudgetWarningEvent

func NewBudgetWarningEvent(turn int, id int, spent, cap float64) BudgetWarningEvent

func (BudgetWarningEvent) Meta

func (e BudgetWarningEvent) Meta() Meta

func (BudgetWarningEvent) Type

func (e BudgetWarningEvent) Type() string

type ChatMsg

type ChatMsg struct {
	Role    string `json:"role"` // "user" | "assistant" | "tool"
	Content string `json:"content"`
}

ChatMsg is a simplified representation for the conversation transcript.

type ConversationView

type ConversationView struct {
	Messages         []ChatMsg     `json:"messages"`
	PendingToolCalls []PendingTool `json:"pendingToolCalls"`
}

func EmptyConversation

func EmptyConversation() ConversationView

type ErrorEvent

type ErrorEvent struct {
	Message     string `json:"message"`
	Recoverable bool   `json:"recoverable"`
	Name        string `json:"name,omitempty"`
	Code        string `json:"code,omitempty"`
	Phase       string `json:"phase,omitempty"`
	// contains filtered or unexported fields
}

func NewErrorEvent

func NewErrorEvent(turn int, id int, msg string, recoverable bool) ErrorEvent

func (ErrorEvent) Meta

func (e ErrorEvent) Meta() Meta

func (ErrorEvent) Type

func (e ErrorEvent) Type() string

type Event

type Event interface {
	Meta() Meta
	Type() string // machine-readable type tag, e.g. "user.message"
	// contains filtered or unexported methods
}

Event is the marker interface. Only implementations in this package satisfy it. Consumers type-switch on the concrete type to access typed fields.

func ReadLog

func ReadLog(path string) ([]Event, error)

ReadLog reads a JSONL file and returns the parsed events.

type Eventizer

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

Eventizer adapts the old event.Sink contract to the typed eventpipe.Sink. It implements event.Sink, converts each old-style Event to its typed counterpart, and forwards it to the typed pipeline.

Usage:

pipe := FanOut(logSink, uiSink)
ez := eventpipe.NewEventizer(pipe)
ctrl := control.New(control.Options{Sink: ez, ...})

The agent emits old-style events; the Eventizer translates them to typed events and feeds the pipeline. Zero agent code changes.

func NewEventizer

func NewEventizer(next Sink) *Eventizer

NewEventizer wraps a typed pipeline sink with the old-style adapter.

func (*Eventizer) Emit

func (ez *Eventizer) Emit(ev *event.Event)

Emit implements event.Sink. It translates the old flat event to a typed eventpipe.Event and forwards it to the pipeline.

type EventizerSink

type EventizerSink struct {
	*Eventizer
}

EventizerSink is a drop-in event.Sink that translates to typed events.

func NewEventizerSink

func NewEventizerSink(pipeline Sink) *EventizerSink

NewEventizerSink creates a sink that accepts old events and forwards typed events to the pipeline. Useful as a drop-in for control.New().

type FileChange

type FileChange struct {
	Path string `json:"path"`
	Mode string `json:"mode"` // "create" | "edit" | "delete"
}

type FrontendBridge

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

FrontendBridge implements eventpipe.Sink by converting typed events back to the old event.Event format and forwarding to an old-style event.Sink. This lets frontends consume typed events through the pipeline without changing their existing ingest/emit code.

Session-cumulative cache tokens (SessionHit/SessionMiss) are tracked automatically across ModelFinalEvent emissions so the old-style event carries both per-turn and cumulative values.

func (*FrontendBridge) Emit

func (b *FrontendBridge) Emit(ev Event)

Emit converts a typed event to old format and forwards it.

type FuncSink

type FuncSink func(Event)

FuncSink adapts a function to Sink.

func (FuncSink) Emit

func (f FuncSink) Emit(ev Event)

type LegacySink

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

LegacySink adapts an eventpipe.Sink to the old event.Sink interface.

func NewLegacySink

func NewLegacySink(pipeline Sink) *LegacySink

func (*LegacySink) Emit

func (s *LegacySink) Emit(ev *event.Event)

type LogConfig

type LogConfig struct {
	Dir       string // directory to write event log files
	SessionID string // session identifier for the filename
}

LogConfig controls event log behaviour.

type LogSink

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

LogSink writes every event to a JSONL file for replay and auditing. Each line is a self-describing {"type":"...","meta":{...},"body":{...}} JSON object.

func NewLogSink

func NewLogSink(cfg LogConfig) (*LogSink, error)

NewLogSink opens (or creates) a JSONL event log file at dir/sessionID.events.jsonl.

func (*LogSink) Close

func (l *LogSink) Close() error

Close flushes and closes the log file. Reports the first prior write error, if any.

func (*LogSink) Emit

func (l *LogSink) Emit(ev Event)

Emit appends one event to the log file. After the first write error, subsequent events are silently dropped; the error is surfaced via Flush() and Close().

func (*LogSink) Flush

func (l *LogSink) Flush() error

Flush writes buffered data to disk. Reports the first prior write error, if any, alongside the flush result.

func (*LogSink) Path

func (l *LogSink) Path() string

Path returns the log file path.

type Meta

type Meta struct {
	ID   int    `json:"id"`
	TS   string `json:"ts"`
	Turn int    `json:"turn"`
}

Meta carries common fields embedded in every concrete event.

type ModelDeltaEvent

type ModelDeltaEvent struct {
	Channel string `json:"channel"` // "content" | "reasoning" | "tool_args"
	Text    string `json:"text"`
	// contains filtered or unexported fields
}

func NewModelDeltaEvent

func NewModelDeltaEvent(turn int, id int, channel, text string) ModelDeltaEvent

func (ModelDeltaEvent) Meta

func (e ModelDeltaEvent) Meta() Meta

func (ModelDeltaEvent) Type

func (e ModelDeltaEvent) Type() string

type ModelFinalEvent

type ModelFinalEvent struct {
	Content          string  `json:"content"`
	ReasoningContent string  `json:"reasoningContent,omitempty"`
	Usage            Usage   `json:"usage,omitempty"`
	CostUSD          float64 `json:"costUsd"`
	ForcedSummary    bool    `json:"forcedSummary,omitempty"`
	// contains filtered or unexported fields
}

func NewModelFinalEvent

func NewModelFinalEvent(turn int, id int, content, reasoning string, usage Usage, cost float64) ModelFinalEvent

func (ModelFinalEvent) Meta

func (e ModelFinalEvent) Meta() Meta

func (ModelFinalEvent) Type

func (e ModelFinalEvent) Type() string

type ModelTurnStartedEvent

type ModelTurnStartedEvent struct {
	Model           string `json:"model"`
	ReasoningEffort string `json:"reasoningEffort"`
	PrefixHash      string `json:"prefixHash"`
	// contains filtered or unexported fields
}

func NewModelTurnStartedEvent

func NewModelTurnStartedEvent(turn int, id int, model, effort, prefixHash string) ModelTurnStartedEvent

func (ModelTurnStartedEvent) Meta

func (e ModelTurnStartedEvent) Meta() Meta

func (ModelTurnStartedEvent) Type

func (e ModelTurnStartedEvent) Type() string

type NoticeEvent

type NoticeEvent struct {
	Text  string      `json:"text"`
	Level NoticeLevel `json:"level"`
	// contains filtered or unexported fields
}

func NewNoticeEvent

func NewNoticeEvent(turn int, id int, text string, level NoticeLevel) NoticeEvent

func (NoticeEvent) Meta

func (e NoticeEvent) Meta() Meta

func (NoticeEvent) Type

func (e NoticeEvent) Type() string

type NoticeLevel

type NoticeLevel int
const (
	NoticeLevelInfo NoticeLevel = iota
	NoticeLevelWarn
)

type PendingTool

type PendingTool struct {
	CallID string `json:"callId"`
	Name   string `json:"name"`
}

type PhaseEvent

type PhaseEvent struct {
	Text string `json:"text"`
	// contains filtered or unexported fields
}

func NewPhaseEvent

func NewPhaseEvent(turn int, id int, text string) PhaseEvent

func (PhaseEvent) Meta

func (e PhaseEvent) Meta() Meta

func (PhaseEvent) Type

func (e PhaseEvent) Type() string

type PlanStep

type PlanStep struct {
	ID     string `json:"id"`
	Title  string `json:"title"`
	Action string `json:"action"`
	Risk   string `json:"risk,omitempty"`
}

type PlanStepChangedEvent

type PlanStepChangedEvent struct {
	StepID string `json:"stepId"`
	Title  string `json:"title,omitempty"`
	Notes  string `json:"notes,omitempty"`
	Status string `json:"status"`
	// contains filtered or unexported fields
}

func NewPlanStepChangedEvent

func NewPlanStepChangedEvent(turn int, id int, stepID, title, notes, status string) PlanStepChangedEvent

func (PlanStepChangedEvent) Meta

func (e PlanStepChangedEvent) Meta() Meta

func (PlanStepChangedEvent) Type

func (e PlanStepChangedEvent) Type() string

type PlanStepView

type PlanStepView struct {
	ID        string `json:"id"`
	Title     string `json:"title"`
	Action    string `json:"action"`
	Risk      string `json:"risk,omitempty"`
	Completed bool   `json:"completed"`
	Notes     string `json:"notes,omitempty"`
}

type PlanSubmittedEvent

type PlanSubmittedEvent struct {
	Steps []PlanStep `json:"steps"`
	Body  string     `json:"body"`
	// contains filtered or unexported fields
}

func NewPlanSubmittedEvent

func NewPlanSubmittedEvent(turn int, id int, steps []PlanStep, body string) PlanSubmittedEvent

func (PlanSubmittedEvent) Meta

func (e PlanSubmittedEvent) Meta() Meta

func (PlanSubmittedEvent) Type

func (e PlanSubmittedEvent) Type() string

type PlanView

type PlanView struct {
	Steps         []PlanStepView `json:"steps"`
	Body          string         `json:"body,omitempty"`
	SubmittedTurn int            `json:"submittedTurn,omitempty"`
}

func EmptyPlan

func EmptyPlan() PlanView

type ProjectionSet

type ProjectionSet struct {
	Conversation ConversationView `json:"conversation"`
	Budget       BudgetView       `json:"budget"`
	Plan         PlanView         `json:"plan"`
	Workspace    WorkspaceView    `json:"workspace"`
}

func Apply

func Apply(state ProjectionSet, ev Event) ProjectionSet

Apply folds one event into all projections.

func EmptyProjections

func EmptyProjections(capUSD float64) ProjectionSet

func Replay

func Replay(events []Event, capUSD float64) ProjectionSet

Replay folds an event sequence into a projection set.

type Reducer

type Reducer[T any] func(view T, ev Event) T

Reducer is a pure function that folds an Event into a view. Deterministic, no I/O, no mutation. Given the same (view, event) pair it always returns the same result.

var BudgetReducer Reducer[BudgetView] = func(v BudgetView, ev Event) BudgetView {
	switch e := ev.(type) {
	case ModelFinalEvent:
		v.SpentUSD += e.CostUSD
		v.PromptTokens += e.Usage.PromptTokens
		v.CompletionTokens += e.Usage.CompletionTokens
		v.CacheHitTokens += e.Usage.CacheHitTokens
		v.CacheMissTokens += e.Usage.CacheMissTokens
		return v
	case BudgetWarningEvent:
		v.Warned = true
		v.SpentUSD = e.SpentUSD
		return v
	case BudgetBlockedEvent:
		v.Blocked = true
		v.SpentUSD = e.SpentUSD
		return v
	default:
		return v
	}
}
var ConversationReducer Reducer[ConversationView] = func(v ConversationView, ev Event) ConversationView {
	switch e := ev.(type) {
	case UserMessageEvent:
		return pushMsg(v, ChatMsg{Role: "user", Content: e.Text})

	case ModelFinalEvent:
		return pushMsg(v, ChatMsg{Role: "assistant", Content: e.Content})

	case ToolIntentEvent:
		return ConversationView{
			Messages:         v.Messages,
			PendingToolCalls: append(v.PendingToolCalls, PendingTool{CallID: e.CallID, Name: e.Name}),
		}

	case ToolResultEvent:
		return ConversationView{
			Messages:         append(v.Messages, ChatMsg{Role: "tool", Content: e.Output}),
			PendingToolCalls: removePending(v.PendingToolCalls, e.CallID),
		}

	case ToolDeniedEvent:
		return ConversationView{
			Messages:         append(v.Messages, ChatMsg{Role: "tool", Content: "denied: " + e.Reason}),
			PendingToolCalls: removePending(v.PendingToolCalls, e.CallID),
		}

	default:
		return v
	}
}
var PlanReducer Reducer[PlanView] = func(v PlanView, ev Event) PlanView {
	switch e := ev.(type) {
	case PlanSubmittedEvent:
		steps := make([]PlanStepView, len(e.Steps))
		for i, s := range e.Steps {
			steps[i] = PlanStepView{
				ID: s.ID, Title: s.Title, Action: s.Action,
				Risk: s.Risk, Completed: false,
			}
		}
		return PlanView{Steps: steps, Body: e.Body, SubmittedTurn: e.meta.Turn}

	case PlanStepChangedEvent:
		for i := range v.Steps {
			if v.Steps[i].ID == e.StepID {
				v.Steps[i].Completed = e.Status == "completed"
				v.Steps[i].Notes = e.Notes
				break
			}
		}
		return v

	default:
		return v
	}
}
var WorkspaceReducer Reducer[WorkspaceView] = func(v WorkspaceView, ev Event) WorkspaceView {
	_ = ev
	return v
}

WorkspaceReducer reduces file-touch and checkpoint events. Currently a placeholder — wire up actual FileTouchedEvent / CheckpointEvent when those typed events are added.

type SessionCompactedEvent

type SessionCompactedEvent struct {
	BeforeMessages int    `json:"beforeMessages"`
	AfterMessages  int    `json:"afterMessages"`
	Reason         string `json:"reason"`
	// contains filtered or unexported fields
}

func NewSessionCompactedEvent

func NewSessionCompactedEvent(turn int, id int, before, after int, reason string) SessionCompactedEvent

func (SessionCompactedEvent) Meta

func (e SessionCompactedEvent) Meta() Meta

func (SessionCompactedEvent) Type

func (e SessionCompactedEvent) Type() string

type SessionOpenedEvent

type SessionOpenedEvent struct {
	Name            string `json:"name"`
	ResumedFromTurn int    `json:"resumedFromTurn"`
	// contains filtered or unexported fields
}

func NewSessionOpenedEvent

func NewSessionOpenedEvent(turn int, id int, name string, resumedFromTurn int) SessionOpenedEvent

func (SessionOpenedEvent) Meta

func (e SessionOpenedEvent) Meta() Meta

func (SessionOpenedEvent) Type

func (e SessionOpenedEvent) Type() string

type Sink

type Sink interface {
	Emit(Event)
}

Sink consumes a typed event stream. Sinks are composable via wrappers (Filter, Map, FanOut, etc.) forming a middleware chain.

var Discard Sink = FuncSink(func(Event) {})

Discard drops every event.

func FanOut

func FanOut(sinks ...Sink) Sink

FanOut broadcasts each event to all sinks. If a sink is nil it's skipped. All sinks see the same event; there is no transformation.

func FanOutByType

func FanOutByType(routes map[string]Sink, fallback Sink) Sink

FanOutByType creates a router that sends each event to the matching sink based on its Type(). Events whose type doesn't match any key go to fallback (which may be nil to drop unmatched).

func Filter

func Filter(next Sink, fn func(Event) bool) Sink

Filter returns a Sink that only passes events matching the predicate.

func Map

func Map(next Sink, fn func(Event) Event) Sink

Map transforms each event before passing it to the next sink. Returning nil drops the event.

func NewFrontendBridge

func NewFrontendBridge(old event.Sink) Sink

NewFrontendBridge wraps an old event.Sink so it can be used in the typed pipeline. The old sink receives converted old-style events.

func Pipe

func Pipe(sinks ...Sink) Sink

Pipe chains sinks left to right: Pipe(a, b, c) emits to a→b→c.

func Tap

func Tap(next Sink, fn func(Event)) Sink

Tap calls fn as a side-effect, then forwards to next. The event is not modified and fn cannot drop it.

type StatusEvent

type StatusEvent struct {
	Text string `json:"text"`
	// contains filtered or unexported fields
}

func NewStatusEvent

func NewStatusEvent(turn int, id int, text string) StatusEvent

func (StatusEvent) Meta

func (e StatusEvent) Meta() Meta

func (StatusEvent) Type

func (e StatusEvent) Type() string

type ToolDeniedEvent

type ToolDeniedEvent struct {
	CallID string `json:"callId"`
	Name   string `json:"name"`
	Reason string `json:"reason"`
	// contains filtered or unexported fields
}

func NewToolDeniedEvent

func NewToolDeniedEvent(turn int, id int, callID, name, reason string) ToolDeniedEvent

func (ToolDeniedEvent) Meta

func (e ToolDeniedEvent) Meta() Meta

func (ToolDeniedEvent) Type

func (e ToolDeniedEvent) Type() string

type ToolIntentEvent

type ToolIntentEvent struct {
	CallID   string `json:"callId"`
	Name     string `json:"name"`
	Args     string `json:"args"`
	ReadOnly bool   `json:"readOnly,omitempty"`
	ParentID string `json:"parentId,omitempty"`
	// contains filtered or unexported fields
}

func NewToolIntentEvent

func NewToolIntentEvent(turn int, id int, callID, name, args string, readOnly bool, parentID string) ToolIntentEvent

func (ToolIntentEvent) Meta

func (e ToolIntentEvent) Meta() Meta

func (ToolIntentEvent) Type

func (e ToolIntentEvent) Type() string

type ToolPreparingEvent

type ToolPreparingEvent struct {
	CallID string `json:"callId"`
	Name   string `json:"name"`
	// contains filtered or unexported fields
}

func NewToolPreparingEvent

func NewToolPreparingEvent(turn int, id int, callID, name string) ToolPreparingEvent

func (ToolPreparingEvent) Meta

func (e ToolPreparingEvent) Meta() Meta

func (ToolPreparingEvent) Type

func (e ToolPreparingEvent) Type() string

type ToolResultEvent

type ToolResultEvent struct {
	CallID     string `json:"callId"`
	Name       string `json:"name"`
	OK         bool   `json:"ok"`
	Output     string `json:"output,omitempty"`
	Err        string `json:"err,omitempty"`
	Truncated  bool   `json:"truncated,omitempty"`
	DurationMs int64  `json:"durationMs,omitempty"`
	// contains filtered or unexported fields
}

func NewToolResultEvent

func NewToolResultEvent(turn int, id int, callID, name string, ok bool, output, errMsg string, truncated bool, durMs int64) ToolResultEvent

func (ToolResultEvent) Meta

func (e ToolResultEvent) Meta() Meta

func (ToolResultEvent) Type

func (e ToolResultEvent) Type() string

type TurnAbortedEvent

type TurnAbortedEvent struct {
	Err      error  `json:"-"`
	Covenant string `json:"covenant"`
	Reason   string `json:"reason"`
	// contains filtered or unexported fields
}

func NewTurnAbortedEvent

func NewTurnAbortedEvent(turn int, id int, err error, covenantID, reason string) TurnAbortedEvent

func (TurnAbortedEvent) Meta

func (e TurnAbortedEvent) Meta() Meta

func (TurnAbortedEvent) Type

func (e TurnAbortedEvent) Type() string

type TurnDoneEvent

type TurnDoneEvent struct {
	Err  error  `json:"-"`
	Text string `json:"text,omitempty"`
	// contains filtered or unexported fields
}

func NewTurnDoneEvent

func NewTurnDoneEvent(turn int, id int, err error) TurnDoneEvent

func (TurnDoneEvent) Meta

func (e TurnDoneEvent) Meta() Meta

func (TurnDoneEvent) Type

func (e TurnDoneEvent) Type() string

type Usage

type Usage struct {
	PromptTokens     int `json:"prompt_tokens,omitempty"`
	CompletionTokens int `json:"completion_tokens,omitempty"`
	TotalTokens      int `json:"total_tokens,omitempty"`
	CacheHitTokens   int `json:"prompt_cache_hit_tokens,omitempty"`
	CacheMissTokens  int `json:"prompt_cache_miss_tokens,omitempty"`
}

type UserMessageEvent

type UserMessageEvent struct {
	Text string `json:"text"`
	// contains filtered or unexported fields
}

func NewUserMessageEvent

func NewUserMessageEvent(turn int, id int, text string) UserMessageEvent

func (UserMessageEvent) Meta

func (e UserMessageEvent) Meta() Meta

func (UserMessageEvent) Type

func (e UserMessageEvent) Type() string

type WireApproval

type WireApproval struct {
	ID      string `json:"id"`
	Tool    string `json:"tool"`
	Subject string `json:"subject"`
}

type WireAsk

type WireAsk struct {
	ID        string         `json:"id"`
	Questions []WireQuestion `json:"questions"`
}

type WireEvent

type WireEvent struct {
	Kind      string        `json:"kind"`
	Text      string        `json:"text,omitempty"`
	Reasoning string        `json:"reasoning,omitempty"`
	Level     string        `json:"level,omitempty"`
	Tool      *WireTool     `json:"tool,omitempty"`
	Usage     *WireUsage    `json:"usage,omitempty"`
	Approval  *WireApproval `json:"approval,omitempty"`
	Ask       *WireAsk      `json:"ask,omitempty"`
	Err       string        `json:"err,omitempty"`
}

WireEvent is the JSON wire format shared by HTTP/SSE and desktop frontends. It mirrors the old toWire contract field-for-field so both transports emit the identical typed stream and a single JS/TS type definition (wireEvent) serves both.

This replaces the previously duplicated toWire in internal/serve/wire.go and desktop/wire.go.

func ToWire

func ToWire(ev Event) WireEvent

ToWire converts an eventpipe.Event to the shared JSON wire format.

type WireOption

type WireOption struct {
	Label       string `json:"label"`
	Description string `json:"description,omitempty"`
}

type WireQuestion

type WireQuestion struct {
	ID      string       `json:"id"`
	Header  string       `json:"header,omitempty"`
	Prompt  string       `json:"prompt"`
	Options []WireOption `json:"options"`
	Multi   bool         `json:"multi,omitempty"`
}

type WireTool

type WireTool struct {
	ID        string `json:"id,omitempty"`
	Name      string `json:"name"`
	Args      string `json:"args,omitempty"`
	Output    string `json:"output,omitempty"`
	Err       string `json:"err,omitempty"`
	ReadOnly  bool   `json:"readOnly"`
	Truncated bool   `json:"truncated,omitempty"`
	Partial   bool   `json:"partial,omitempty"`
	ParentID  string `json:"parentId,omitempty"`
}

type WireUsage

type WireUsage struct {
	PromptTokens           int     `json:"promptTokens"`
	CompletionTokens       int     `json:"completionTokens"`
	TotalTokens            int     `json:"totalTokens"`
	CacheHitTokens         int     `json:"cacheHitTokens"`
	CacheMissTokens        int     `json:"cacheMissTokens"`
	ReasoningTokens        int     `json:"reasoningTokens,omitempty"`
	SessionCacheHitTokens  int     `json:"sessionCacheHitTokens"`
	SessionCacheMissTokens int     `json:"sessionCacheMissTokens"`
	CostUSD                float64 `json:"costUsd,omitempty"`
}

type WorkspaceView

type WorkspaceView struct {
	FilesTouched   []FileChange `json:"filesTouched"`
	LastCheckpoint string       `json:"lastCheckpoint,omitempty"`
}

func EmptyWorkspace

func EmptyWorkspace() WorkspaceView

Jump to

Keyboard shortcuts

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