monitor

package
v0.2.6-alpha.1 Latest Latest
Warning

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

Go to latest
Published: May 22, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package monitor hosts the deferred Monitor tool — a background process watcher that streams stdout lines as agent-loop notifications.

The tool spawns the configured shell command in its own process group bound to the host's RootCtx (so monitor goroutines survive the LLM call that spawned them). For each stdout line the goroutine writes a MonitorEvent to the host's queue and fires a signal so an idle agent wakes up to react; events arriving while the loop is busy are folded into the next iteration via drainMonitorEvents.

Index

Constants

View Source
const MonitorDomain = "monitors"

MonitorDomain is the observable.Change.Domain for monitor task changes.

Variables

This section is empty.

Functions

func GenerateID

func GenerateID() string

GenerateID returns "m" + 8 random base-36 chars. Distinct prefix from shell.GenerateID's "b" so a transcript can disambiguate at a glance.

func Names

func Names() []tools.ToolName

Names lists every tool name this package contributes.

Types

type MonitorEvent

type MonitorEvent struct {
	MonitorID string
	Line      string
	At        time.Time
	Closing   bool
}

MonitorEvent is one stdout line streamed by a running monitor. Closing is true on the final event when the underlying process exits (or task_stop is called) — drain folds the closing event into the system-reminder and the TUI strip flips the chip to Stopped.

type MonitorEventQueue

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

MonitorEventQueue is the FIFO queue of streamed lines from every running monitor. The agent's drainMonitorEvents helper pulls events at iter start and folds them into a single <system-reminder> RoleUser message; events are never persisted beyond the drain.

func NewMonitorEventQueue

func NewMonitorEventQueue() *MonitorEventQueue

NewMonitorEventQueue returns an empty queue.

func (*MonitorEventQueue) Drain

func (q *MonitorEventQueue) Drain() []MonitorEvent

Drain returns every queued event in arrival order and clears the queue. Returns nil when empty so the drain helper can short-circuit.

func (*MonitorEventQueue) Enqueue

func (q *MonitorEventQueue) Enqueue(ev MonitorEvent)

Enqueue pushes one event. Callers (monitor goroutines) call this before signalling the agent so the drain at iter start sees the event regardless of how the pump's CAS races.

func (*MonitorEventQueue) HasPending

func (q *MonitorEventQueue) HasPending() bool

HasPending reports whether the queue carries any undrained events. Cheap mu-read used by the agent loop's end-of-turn re-check.

type MonitorHost

type MonitorHost interface {
	// MonitorTaskStore returns the agent's monitor catalog.
	MonitorTaskStore() *MonitorTaskStore
	// MonitorEventQueue returns the per-agent queue every monitor
	// streams events into.
	MonitorEventQueue() *MonitorEventQueue
	// RootCtx returns the agent-lifetime context; monitor goroutines
	// bind here, not the per-call ctx.
	RootCtx() context.Context
	// AgentID is the spawning agent's id.
	AgentID() string
	// NotifyMonitorEvent fires the agent's signal pump for one streamed
	// event. Non-blocking; the queue is the durable backstop.
	NotifyMonitorEvent(ev MonitorEvent)
}

MonitorHost is the narrow surface a MonitorTool reads from its host (*toolset.ToolState in production). Mirrors shell.BgTaskHost so the two implementations stay parallel.

type MonitorStatus

type MonitorStatus string

MonitorStatus is the lifecycle state of one Monitor task. Distinct from shell.BgTaskStatus because monitor tasks can be long-lived (persistent loops) and don't carry a single exit code — they accumulate events.

Transitions:

Monitoring → Stopped   (process exited cleanly OR task_stop called)
Monitoring → Failed    (process spawn failed)
const (
	Monitoring MonitorStatus = "monitoring"
	Stopped    MonitorStatus = "stopped"
	Failed     MonitorStatus = "failed"
)

type MonitorTask

type MonitorTask struct {
	MonitorTaskSnapshot
	Cancel context.CancelFunc
}

MonitorTask is the live record the store mutates. Cancel terminates the underlying process — task_stop calls it; the goroutine then transitions the snapshot to Stopped.

type MonitorTaskSnapshot

type MonitorTaskSnapshot struct {
	ID          string
	Command     string
	Description string
	Status      MonitorStatus
	EventCount  int
	StartedAt   time.Time
	StoppedAt   time.Time
	AgentID     string
}

MonitorTaskSnapshot is the public shape of one monitor entry. The event count is read at snapshot time; events themselves live in the per-agent MonitorEventQueue, not on the snapshot.

type MonitorTaskStore

type MonitorTaskStore struct {
	*observable.Observable
	// contains filtered or unexported fields
}

MonitorTaskStore is the agent-owned catalog of monitor tasks. Same shape as shell.BgTaskStore: embedded Observable for TUI fanout, internal mutex, lifecycle methods (Add / Complete / Stop) + query methods (Get / Snapshot).

Unlike BgTaskStore there is no DrainCompleted — monitors don't fold their snapshot into the conversation when they stop. The per-monitor closing event (Closing:true) carries that signal; the snapshot just transitions to Stopped/Failed and stays in the store until the session ends.

func NewMonitorTaskStore

func NewMonitorTaskStore() *MonitorTaskStore

NewMonitorTaskStore returns an empty store.

func (*MonitorTaskStore) Add

Add registers a freshly-spawned monitor. cancel kills the underlying process on task_stop or root-ctx cancel. Emits a "started" Change so the strip renders the chip immediately.

func (*MonitorTaskStore) Complete

func (s *MonitorTaskStore) Complete(id string, status MonitorStatus)

Complete transitions the monitor to a terminal state (Stopped / Failed). Clears Cancel so task_stop on a finished monitor is a clean no-op. Emits a Change matching the terminal Op for renderers.

func (*MonitorTaskStore) Domain

func (s *MonitorTaskStore) Domain() string

Domain returns the observable store domain. Implements observable.Store.

func (*MonitorTaskStore) Get

Get returns one task snapshot. ok=false when unknown.

func (*MonitorTaskStore) IncEventCount

func (s *MonitorTaskStore) IncEventCount(id string)

IncEventCount bumps the event counter for a running monitor. Called by the monitor goroutine each time it streams a line. Emits an "event" Change for the strip to flicker.

func (*MonitorTaskStore) Snapshot

func (s *MonitorTaskStore) Snapshot() []MonitorTaskSnapshot

Snapshot returns every monitor in started-at order. Used by the TUI strip.

func (*MonitorTaskStore) Stop

Stop signals the named monitor to terminate. ok=false when unknown or already terminal.

type MonitorTool

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

MonitorTool spawns a long-running shell command and streams its stdout lines back to the agent as MonitorEvents. host supplies the MonitorTaskStore + event queue + signal sender; without it the tool reports a clean error rather than panicking.

func NewMonitor

func NewMonitor(host MonitorHost) *MonitorTool

NewMonitor constructs the production MonitorTool. The toolset factory passes the agent's *ToolState as host so per-event delivery routes through the agent's signal pump.

func (*MonitorTool) Description

func (t *MonitorTool) Description() string

func (*MonitorTool) Execute

func (t *MonitorTool) Execute(_ context.Context, logger *slog.Logger, raw json.RawMessage) (tools.Result, error)

func (*MonitorTool) Name

func (t *MonitorTool) Name() string

func (*MonitorTool) Schema

func (t *MonitorTool) Schema() json.RawMessage

Jump to

Keyboard shortcuts

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