attention

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Aug 15, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Index

Constants

View Source
const RunStateStaleAfter = time.Hour

Variables

View Source
var (
	ErrInvalidGeneration = errors.New("invalid completion generation")
	ErrStaleGeneration   = errors.New("completion generation changed")
)
View Source
var ErrRunStateNotFound = errors.New("run state not found")

Functions

This section is empty.

Types

type Assertion

type Assertion struct {
	Signal     EvidenceSignal
	Source     EvidenceSource
	Confidence EvidenceConfidence
	UpdatedAt  time.Time
	Reason     RunReason
	TaskID     string
}

Assertion preserves one source's raw lifecycle claim. Keeping assertions separate lets the reducer apply precedence and detect equal-authority conflicts instead of flattening evidence in an adapter.

type Evidence

type Evidence struct {
	AgentPresent           bool
	AgentEnabled           bool
	Assertions             []Assertion
	CompletionGeneration   uint64
	AcknowledgedGeneration uint64
}

Evidence contains no prompt or hook payload bodies. Completion generations are service-owned metadata; their persistence starts in the next phase.

func Acknowledge

func Acknowledge(e Evidence, expected uint64) (Evidence, error)

Acknowledge is idempotent for the current completion. An older generation can never clear a newer completion.

func EvidenceFromHook

func EvidenceFromHook(evt hooks.Event, enabled bool, completionGeneration, acknowledgedGeneration uint64) Evidence

EvidenceFromHook translates only installed adapter event names with proven meanings. Notification is permission-blocked by the managed hook contract. Unknown names remain unknown; terminal-derived cmdDone is intentionally not a hook completion source.

type EvidenceConfidence

type EvidenceConfidence string
const (
	ConfidenceAuthoritative EvidenceConfidence = "authoritative"
	ConfidenceInferred      EvidenceConfidence = "inferred"
	ConfidenceFallback      EvidenceConfidence = "fallback"
)

type EvidenceSignal

type EvidenceSignal string
const (
	SignalWorking   EvidenceSignal = "working"
	SignalBlocked   EvidenceSignal = "blocked"
	SignalCompleted EvidenceSignal = "completed"
	SignalIdle      EvidenceSignal = "idle"
	SignalUnknown   EvidenceSignal = "unknown"
)

type EvidenceSource

type EvidenceSource string
const (
	SourceHook             EvidenceSource = "hook"
	SourceTask             EvidenceSource = "task"
	SourceTerminalDetector EvidenceSource = "terminal_detector"
	SourceProcessDetector  EvidenceSource = "process_detector"
	SourceTimeout          EvidenceSource = "timeout"
)

type Projection

type Projection struct {
	State                RunState           `json:"state"`
	Source               EvidenceSource     `json:"source,omitempty"`
	Confidence           EvidenceConfidence `json:"confidence,omitempty"`
	UpdatedAt            time.Time          `json:"updated_at,omitempty"`
	Reason               RunReason          `json:"reason,omitempty"`
	TaskID               string             `json:"task_id,omitempty"`
	Unseen               bool               `json:"unseen,omitempty"`
	CompletionGeneration uint64             `json:"completion_generation,omitempty"`
}

func Reduce

func Reduce(e Evidence, now time.Time) (Projection, bool)

Reduce deterministically selects the strongest fresh assertion. Task state outranks hooks; within one source, newer evidence wins. Conflicting assertions with equal source, confidence, and timestamp degrade to unknown. ok=false suppresses disabled agents and sessions with no foreground agent.

type RunReason

type RunReason string

RunReason is a bounded explanation safe for later wire contracts.

const (
	ReasonPermission RunReason = "permission"
	ReasonQuestion   RunReason = "question"
	ReasonError      RunReason = "error"
	ReasonCompleted  RunReason = "completed"
	ReasonStale      RunReason = "stale"
)

type RunState

type RunState string

RunState is daemon-owned execution state. It is deliberately separate from session selection and foreground-process presence, neither of which proves that an agent is working.

const (
	RunStateWorking RunState = "working"
	RunStateBlocked RunState = "blocked"
	RunStateDone    RunState = "done"
	RunStateIdle    RunState = "idle"
	RunStateUnknown RunState = "unknown"
)

type RunStateStore

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

RunStateStore owns canonical run-state assembly separately from PTY restore state. Only bounded completion metadata is durable; prompt and hook bodies never enter this file.

func NewRunStateStore

func NewRunStateStore(path string) (*RunStateStore, error)

func (*RunStateStore) Acknowledge

func (s *RunStateStore) Acknowledge(sessionID string, expected uint64) (bool, error)

func (*RunStateStore) ClearTask

func (s *RunStateStore) ClearTask(sessionID, taskID string, now time.Time) (bool, error)

ClearTask removes only the matching task-owned assertion. It is used when a coordination gate resolves before the queued task has emitted new lifecycle evidence, preventing stale authoritative blocked state from surviving.

func (*RunStateStore) ObserveHook

func (s *RunStateStore) ObserveHook(sessionID, agent, agentSessionID string, evt hooks.Event, enabled bool, now time.Time) (bool, error)

ObserveHook records trusted metadata after the server has resolved the hook to exactly one daemon PTY. SessionEnd deliberately leaves unseen completion intact; explicit session destruction owns cleanup.

func (*RunStateStore) ObserveTask

func (s *RunStateStore) ObserveTask(sessionID, agent, taskID string, signal EvidenceSignal, reason RunReason, enabled bool, now time.Time) (bool, error)

ObserveTask records causal task lifecycle evidence. Task evidence is authoritative and intentionally replaces weaker hook/process assertions for the target session until a newer trusted signal arrives.

func (*RunStateStore) ProjectAgentSession

func (s *RunStateStore) ProjectAgentSession(agentSessionID string, enabled func(string) bool, now time.Time) (*Projection, bool)

ProjectAgentSession refuses to guess when more than one PTY claims the same agent-session identity.

func (*RunStateStore) ProjectSession

func (s *RunStateStore) ProjectSession(sessionID string, enabled func(string) bool, now time.Time) (*Projection, bool)

func (*RunStateStore) Remove

func (s *RunStateStore) Remove(sessionID string) error

type Snapshot

type Snapshot struct {
	State      string `json:"state"`
	Task       string `json:"task,omitempty"`
	NextAction string `json:"next_action,omitempty"`
	Summary    string `json:"summary,omitempty"`
	At         string `json:"at,omitempty"`
}

Snapshot is one row's lifecycle state. JSON tags match iOS's AttentionSnapshot Codable. `At` is RFC3339 of the source hook event.

type Tracker

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

Tracker is the per-session-event state owner. Goroutine-safe.

func New

func New() *Tracker

New constructs an empty tracker.

func (*Tracker) Clear

func (t *Tracker) Clear(agentSessionID string)

Clear removes state for one agent session. Called when the agent reports SessionEnd so the row's attention badge goes neutral after exit.

func (*Tracker) Snapshot

func (t *Tracker) Snapshot(agentSessionID string) *Snapshot

Snapshot returns the current lifecycle state for one agent session id, or nil if the tracker has no events for it. Caller passes the agent session id (NOT the daemon PTY session id) — same field iOS uses to match the row.

func (*Tracker) Update

func (t *Tracker) Update(evt hooks.Event) bool

Update records a hook event for its owning agent session. Called from the hook ingest path on every event. Events with no SessionID are dropped (can't attribute them). Returns whether the visible lifecycle STATE changed (active/ready/idle/stale transition) so callers can gate expensive unified- list refresh publishes — a burst of same-state tool events (PreToolUse / PostToolUse, all "active") collapses to zero publishes instead of flooding iOS with disk-walking refetches on every tool call.

Jump to

Keyboard shortcuts

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