binding

package
v0.260806.1 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2026 License: MPL-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package binding describes which channel a scenario should use for a given event. Bindings live alongside bot settings (the host persists them as a JSON-encoded Scenarios list per bot) and are resolved purely from the small BotInfo record the host hands the resolver — binding itself depends on no host type.

The binding type is generic across scenarios — fields beyond Name / ChatID / Events are stored as a free-form Options map so new scenarios can add scenario-specific settings without changing the schema or the generic resolver.

Index

Constants

View Source
const RemoteAgentScenario = "remote_agent"

RemoteAgentScenario is the mount name for the remote-agent purpose (controlling Claude Code / SmartGuide from chat). Unlike outbound scenarios (e.g. claude_code hooks) it has no registered plugin — it is an inbound mount stored in the same per-bot Scenarios list so a bot's purposes all live in one place. See ScenarioMounted for the on/off semantics.

Variables

This section is empty.

Functions

func OutboundScenarioMounted added in v0.260723.1

func OutboundScenarioMounted(scenariosJSON string) bool

OutboundScenarioMounted reports whether the bot serves the notify purpose: it has at least one outbound scenario binding (any name other than the remote_agent inbound mount) that is not turned off. This is the mount predicate for the notify consumer — a bot with only outbound bindings runs as a pure notification/interaction surface even when remote_agent is off.

Unlike ScenarioMounted, absence does NOT count as mounted: a bot with no outbound bindings has nothing for the resolver to route to it, so registering a channel would be dead weight. A malformed blob likewise counts as not mounted here — the remote_agent side already fails open, which keeps the bot online for diagnosis.

func ScenarioMounted added in v0.260723.1

func ScenarioMounted(scenariosJSON, name string) bool

ScenarioMounted reports whether the named scenario is mounted (active) on a bot given its raw Scenarios JSON.

A scenario is mounted when an explicit binding with that name is present and not turned off (Enabled nil or true). For backward compatibility with bots configured before mounts existed, the ABSENCE of a binding for name also counts as mounted — otherwise every legacy bot would stop serving. To turn a mount off you therefore write an explicit binding with enabled:false rather than removing it. A malformed Scenarios blob is treated as mounted so a bad row never silently takes a bot offline.

func SetScenarioEnabled added in v0.260723.1

func SetScenarioEnabled(scenariosJSON, name string, enabled bool) (string, error)

SetScenarioEnabled returns scenariosJSON with the named scenario's mount set to enabled. If a binding with that name exists its enabled flag is updated in place; otherwise a new {name, enabled} binding is appended. All other bindings and their fields (chat_id, options, …) are preserved verbatim, because the operation is done on the raw object list rather than the typed Binding (which drops unknown fields into Options).

Types

type Binding

type Binding struct {
	// Name matches the scenario plugin Name() and the :scenario URL
	// segment of /tingly/:scenario/...
	Name string `json:"name"`
	// ChatID is the IM chat the bot routes to. Channels look this up
	// when delivering Send / Prompt.
	ChatID string `json:"chat_id"`
	// Events optionally restricts which event names this binding
	// handles. Empty list = all events.
	Events []string `json:"events,omitempty"`
	// Enabled is the mount switch. nil means "on" so that bindings written
	// before the switch existed (and outbound bindings, which are always
	// active when present) keep working. Set explicitly to false to mount a
	// scenario but keep it turned off.
	Enabled *bool `json:"enabled,omitempty"`
	// Options carries scenario-specific configuration the resolver
	// returns verbatim to the plugin (e.g. permission policy for the
	// claude_code scenario).
	Options map[string]any `json:"-"`
}

Binding declares how a single bot serves a named scenario.

type BotInfo added in v0.260806.1

type BotInfo struct {
	UUID      string
	Platform  string
	Name      string
	Scenarios string // raw JSON-encoded binding list, parsed by binding
}

BotInfo is the subset of a bot's settings the resolver needs. The host maps its own settings record onto this so the binding package stays free of any host-side type dependency.

type Resolved

type Resolved struct {
	Binding  Binding
	BotUUID  string
	Platform string
	BotName  string
}

Resolved is what the resolver returns to the plugin: the binding itself plus the bot identity needed to look up a Channel.

type Resolver

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

Resolver matches (scenario, event) to a single bot binding by scanning enabled bot settings. Read-only and safe for concurrent use.

func NewResolver

func NewResolver(store Store) *Resolver

NewResolver constructs a resolver backed by the given store.

func (*Resolver) Resolve

func (r *Resolver) Resolve(scenario, event string) (*Resolved, error)

Resolve returns the first enabled bot whose binding matches scenario + event. ok=false means no binding exists; err is non-nil only on store failures.

type Store

type Store interface {
	ListEnabledBindings() ([]BotInfo, error)
}

Store is the subset of the imbot settings store the resolver needs. Defining it as an interface keeps the resolver testable and lets the host bridge its own persistence type without leaking it in here.

Jump to

Keyboard shortcuts

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