Documentation
¶
Overview ¶
Package adapters defines backend-neutral agent events and the adapters that derive them from normalized terminal text.
Index ¶
- Constants
- Variables
- func IsSensitiveText(value string) bool
- type Adapter
- type ClaudeAdapter
- type CodexAdapter
- type Decision
- type Descriptor
- type DetectionState
- type Event
- type EventType
- type Factory
- type GenericRegexAdapter
- type Hooks
- type Pattern
- type Processor
- func (p *Processor) Acknowledge(eventID string) error
- func (p *Processor) Consume(chunk []byte) error
- func (p *Processor) DetectionWindowLen() int
- func (p *Processor) IsBlocked() bool
- func (p *Processor) MarkProcessExitEvent(exitCode *int, failed bool) Event
- func (p *Processor) NewProcessExitEvent(exitCode *int, failed bool) Event
- func (p *Processor) Output() string
- func (p *Processor) Pending() *Event
- func (p *Processor) ReconcileSnapshot(raw []byte) (*Event, bool, error)
- func (p *Processor) Resolve(eventID string, deliver func() error) error
- func (p *Processor) Restore(event Event) error
- func (p *Processor) Revision() uint64
- func (p *Processor) Run(ctx context.Context, reader io.Reader) error
- func (p *Processor) SendLine(ctx context.Context, line string, deliver func([]byte) error) error
- func (p *Processor) WaitSemanticEvents()
- type Registry
- type RiskLevel
- type Status
Constants ¶
const ( // ClaudeID identifies the experimental Claude Code adapter. Its vendor // rules are intentionally limited to anonymized prompts observed with the // version documented alongside the fixtures. ClaudeID = "claude" )
const ( // CodexID is experimental and intentionally limited to interactions backed // by the anonymized captures in testdata/codex. CodexID = "codex" )
const GenericID = "generic"
const MaxLineBytes = 4096
MaxLineBytes is the maximum encoded line accepted by the safe line-input boundary, before its terminating carriage return is appended.
Variables ¶
var ( ErrUnknownAdapter = errors.New("adaptateur inconnu") ErrDecisionUnsupported = errors.New("décision non prise en charge") ErrEventMismatch = errors.New("événement en attente différent") ErrProcessorTerminated = errors.New("flux sémantique de l'adaptateur terminé") )
var ( // ErrEventPending reports that an actionable event must be resolved before // ordinary line input can be delivered. ErrEventPending = errors.New("événement actionable en attente") // ErrInvalidLine reports line input which cannot be encoded unambiguously. ErrInvalidLine = errors.New("ligne terminal invalide") // ErrLineUnsupported reports that a transport has no atomic line boundary. ErrLineUnsupported = errors.New("envoi de ligne non pris en charge") // ErrLineDeliveryUncertain reports that a transport was called but could // not prove whether zero, some, or all line bytes reached the target. The // original transport error is deliberately not retained: it may echo the // submitted text and must never escape through errors.Unwrap. ErrLineDeliveryUncertain = errors.New("livraison de ligne incertaine") )
Functions ¶
func IsSensitiveText ¶
Types ¶
type Adapter ¶
type Adapter interface {
ID() string
Detect(state *DetectionState, chunk []byte) ([]Event, error)
EncodeDecision(event Event, decision Decision, manualInput string) ([]byte, error)
}
Adapter interprets normalized, ANSI-free terminal text. Implementations do not own processes, PTYs, tmux sessions, rendered history or audit sinks.
type ClaudeAdapter ¶
type ClaudeAdapter struct {
// contains filtered or unexported fields
}
ClaudeAdapter recognizes only prompts backed by the anonymized Claude Code 2.1.59 fixtures. Configured intercept_patterns retain their configured order and take priority, preserving the semantics of existing configurations.
The adapter remains experimental: no automatic allow or deny byte sequence is claimed because the highlighted TUI selection can change independently of the prompt text visible to Relayer.
func NewClaudeAdapter ¶
func NewClaudeAdapter(patterns []Pattern) (*ClaudeAdapter, error)
NewClaudeAdapter validates both the observed rules and every configured intercept_pattern before a session starts.
func (*ClaudeAdapter) Detect ¶
func (a *ClaudeAdapter) Detect(state *DetectionState, chunk []byte) ([]Event, error)
Detect delegates bounded stream handling and legacy regex behavior to the generic adapter, then enriches only rules tied to real Claude Code fixtures.
func (*ClaudeAdapter) EncodeDecision ¶
func (a *ClaudeAdapter) EncodeDecision(event Event, decision Decision, manualInput string) ([]byte, error)
EncodeDecision preserves exact manual input compatibility. Automatic allow and deny remain unsupported until selection-independent bytes are verified.
func (*ClaudeAdapter) ID ¶
func (*ClaudeAdapter) ID() string
type CodexAdapter ¶
type CodexAdapter struct {
// contains filtered or unexported fields
}
CodexAdapter recognizes only prompts captured from the CLI version recorded in testdata/codex. Configured intercept_patterns remain a complete fallback; this wrapper does not silently replace or weaken them.
func NewCodexAdapter ¶
func NewCodexAdapter(patterns []Pattern) (*CodexAdapter, error)
NewCodexAdapter validates and copies the legacy intercept_patterns used by the generic fallback.
func (*CodexAdapter) Detect ¶
func (a *CodexAdapter) Detect(state *DetectionState, chunk []byte) ([]Event, error)
Detect gives configured intercept_patterns priority so enabling the Codex adapter cannot change an existing policy's event semantics. Verified Codex prompts are considered only when no configured pattern matches. Probes are value copies, so a chunk is committed to the bounded DetectionState exactly once.
func (*CodexAdapter) EncodeDecision ¶
func (a *CodexAdapter) EncodeDecision(event Event, decision Decision, manualInput string) ([]byte, error)
EncodeDecision supports only byte sequences verified against the captured CLI. Generic fallback events retain the established manual-input behavior.
func (*CodexAdapter) ID ¶
func (*CodexAdapter) ID() string
type Decision ¶
type Decision string
Decision is deliberately limited to actions represented by current code. Adapters may reject allow or deny when they cannot encode the action reliably; callers must then retain the pending event for human input.
type Descriptor ¶
Descriptor is safe to display in diagnostics and documentation.
type DetectionState ¶
type DetectionState struct {
SessionID string
AgentID string
AdapterID string
// contains filtered or unexported fields
}
DetectionState is the bounded, per-session state supplied to an Adapter. A state must never be shared by two terminal sessions.
func NewDetectionState ¶
func NewDetectionState(sessionID, agentID, adapterID string) *DetectionState
NewDetectionState creates independent state for one agent session.
func (*DetectionState) IsBlocked ¶
func (s *DetectionState) IsBlocked() bool
IsBlocked reports whether an actionable event still awaits a decision.
func (*DetectionState) Pending ¶
func (s *DetectionState) Pending() *Event
Pending returns a defensive copy of the current actionable event.
type Event ¶
type Event struct {
ID string
Signature string
Sequence uint64
SessionID string
AgentID string
Adapter string
Type EventType
Summary string
Match string
Sensitive bool
Risk RiskLevel
Timestamp time.Time
Metadata map[string]string
}
Event is the single semantic representation shared by adapters, backends, snapshots and the TUI. ID identifies one occurrence; Signature is stable for equivalent normalized content and is used only while reconciling duplicates.
func NewProcessExitEvent ¶
func NewProcessExitEvent(sessionID, agentID, adapterID string, sequence uint64, exitCode *int, failed bool) Event
NewProcessExitEvent creates the sole lifecycle event currently represented in the semantic stream. Metadata contains only a numeric exit code.
func (Event) Actionable ¶
Actionable reports whether Relayer must pause for a human decision.
type EventType ¶
type EventType string
EventType describes an observation with a concrete meaning in Relayer. Output invalidations and backend failures intentionally remain transport signals: they are not agent events.
type GenericRegexAdapter ¶
type GenericRegexAdapter struct {
// contains filtered or unexported fields
}
GenericRegexAdapter is the stable compatibility adapter for existing intercept_patterns. It receives only normalized text from Processor.
func NewGenericRegexAdapter ¶
func NewGenericRegexAdapter(patterns []Pattern) (*GenericRegexAdapter, error)
NewGenericRegexAdapter validates and defensively copies all expressions.
func (*GenericRegexAdapter) Detect ¶
func (a *GenericRegexAdapter) Detect(state *DetectionState, chunk []byte) ([]Event, error)
Detect preserves pattern order and reports at most one actionable event while another occurrence is pending. A match may span chunks, but it must reach the active terminal line affected by the newest normalized chunk.
func (*GenericRegexAdapter) EncodeDecision ¶
func (*GenericRegexAdapter) ID ¶
func (*GenericRegexAdapter) ID() string
type Hooks ¶
type Hooks struct {
OnOutput func()
OnEvent func(Event)
}
Hooks are invoked synchronously after Processor releases its state lock. OnEvent may inspect Processor state; process termination remains the responsibility of the owning backend rather than an event callback.
type Pattern ¶
Pattern is the backward-compatible representation of intercept_patterns.
func DefaultPatterns ¶
func DefaultPatterns() []Pattern
type Processor ¶
type Processor struct {
// contains filtered or unexported fields
}
Processor separates raw transport bytes, normalized detection text and the bounded sanitized text rendered by Bubble Tea. Raw bytes are never retained.
func NewProcessor ¶
func (*Processor) Acknowledge ¶
func (*Processor) Consume ¶
Consume accepts raw terminal bytes, strips fragmented ANSI sequences and sends only normalized text to the adapter.
func (*Processor) DetectionWindowLen ¶
func (*Processor) MarkProcessExitEvent ¶
MarkProcessExitEvent atomically terminates any pending interaction and reserves the next occurrence sequence under the same lock used by Detect and SendLine. It deliberately does not wait for earlier semantic hooks: a process owner can mark the transport closed immediately after Wait, perform bounded descendant cleanup, then call WaitSemanticEvents before publishing the returned process_exit event.
func (*Processor) NewProcessExitEvent ¶
NewProcessExitEvent marks the processor terminated, then preserves the historical ordering guarantee that every earlier semantic hook completes before the process_exit event is returned to its caller.
func (*Processor) ReconcileSnapshot ¶
ReconcileSnapshot uses the last active logical line for generic detection. A vendor adapter may additionally fingerprint only its verified prompt block so a resize remains idempotent while a successive prompt discovered after an attach receives a fresh occurrence ID. An unchanged snapshot after a successful acknowledgement cannot resurrect the old event.
func (*Processor) Resolve ¶
Resolve serializes a decision with detection. The pending occurrence is cleared only after delivery succeeds; terminal output arriving concurrently is processed afterwards, so an immediate second prompt cannot be overwritten by rollback of the first one.
func (*Processor) Revision ¶
Revision returns the latest semantic occurrence sequence for snapshots.
func (*Processor) SendLine ¶
SendLine serializes ordinary line input with event detection and process termination. It never resolves or acknowledges an event. Delivery happens under the same lock as Detect, so either the line is sent first or a prompt becomes pending first; the two outcomes cannot race past one another.
func (*Processor) WaitSemanticEvents ¶
func (p *Processor) WaitSemanticEvents()
WaitSemanticEvents waits until every actionable event reserved before process termination has reached its hook. It must stay outside p.mu because hooks are allowed to inspect Processor state.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry resolves explicit adapters and executable-name hints. Generic is always installed as the final fallback. Claude and Codex remain experimental and recognize only interactions backed by anonymized fixtures.
func NewRegistry ¶
NewRegistry builds the production registry around legacy regex patterns.
func (*Registry) Descriptors ¶
func (r *Registry) Descriptors() []Descriptor
Descriptors returns a deterministic, defensive maturity inventory.