channels

package
v0.17.0 Latest Latest
Warning

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

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

Documentation

Overview

Package channels defines the channel adapter architecture for exposing self-hosted agents via messaging platforms like Slack and Telegram.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ResolveEnvVars

func ResolveEnvVars(cfg *ChannelConfig) map[string]string

ResolveEnvVars inspects cfg.Settings for keys ending in "_env" and resolves them from the environment. For example, a setting "bot_token_env": "SLACK_BOT_TOKEN" produces {"bot_token": os.Getenv("SLACK_BOT_TOKEN")}. Non-env settings are passed through unchanged.

func StartDeliverSpan added in v0.16.0

func StartDeliverSpan(ctx context.Context, adapter string, event *ChannelEvent) (context.Context, trace.Span, func(*error))

StartDeliverSpan opens a `channel.<adapter>.deliver` span around an inbound channel adapter's per-message handler and returns a finish closure that records the error and ends the span. The span attributes mirror the upstream-system metadata an operator needs to pivot from the trace back to the Slack thread / Telegram chat / Teams message that produced this invocation. Issue #187.

The span PARENTS the internal A2A POST that `forge-cli/channels/router.go` issues, because that router injects the W3C traceparent from the calling ctx onto the outbound HTTP request — the A2A server's `a2a.tasks/send` span then nests under this delivery span instead of starting as an orphan root.

Usage shape (defer captures the named return so finish sees the final err value):

go func() {
    ctx, _, finish := channels.StartDeliverSpan(ctx, "slack", event)
    var err error
    defer finish(&err)
    // ... handler work mutates err ...
}()

When tracing is disabled the global tracer is a no-op and Start returns an empty span with zero allocations — safe to call on every inbound message regardless of tracing posture.

Types

type Attachment

type Attachment struct {
	Name     string `json:"name,omitempty"`
	MimeType string `json:"mime_type,omitempty"`
	URL      string `json:"url,omitempty"`
}

Attachment represents a file or media item attached to a channel message.

type ChannelConfig

type ChannelConfig struct {
	Adapter     string            `yaml:"adapter"`
	WebhookPort int               `yaml:"webhook_port,omitempty"`
	WebhookPath string            `yaml:"webhook_path,omitempty"`
	Settings    map[string]string `yaml:"settings,omitempty"`
}

ChannelConfig holds per-adapter configuration loaded from YAML.

type ChannelEvent

type ChannelEvent struct {
	Channel     string          `json:"channel"`
	WorkspaceID string          `json:"workspace_id"`
	UserID      string          `json:"user_id"`
	ThreadID    string          `json:"thread_id,omitempty"`
	MessageID   string          `json:"message_id,omitempty"` // per-message ID for reply targeting
	Message     string          `json:"message"`
	Attachments []Attachment    `json:"attachments,omitempty"`
	Raw         json.RawMessage `json:"raw,omitempty"`
}

ChannelEvent is the normalized representation of an inbound message from any supported platform.

type ChannelPlugin

type ChannelPlugin interface {
	// Name returns the adapter name (e.g. "slack", "telegram").
	Name() string
	// Init configures the plugin from a ChannelConfig.
	Init(cfg ChannelConfig) error
	// Start begins listening for events and dispatching them to handler.
	// It blocks until ctx is cancelled.
	Start(ctx context.Context, handler EventHandler) error
	// Stop gracefully shuts down the plugin.
	Stop() error
	// NormalizeEvent converts raw platform bytes into a ChannelEvent.
	NormalizeEvent(raw []byte) (*ChannelEvent, error)
	// SendResponse delivers an A2A response back to the originating platform.
	SendResponse(event *ChannelEvent, response *a2a.Message) error
}

ChannelPlugin is the interface every channel adapter must implement.

type EventHandler

type EventHandler func(ctx context.Context, event *ChannelEvent) (*a2a.Message, error)

EventHandler is the callback signature provided by the router. The plugin calls it when a message arrives; the handler forwards the event to the A2A server and returns the agent's response.

type Registry

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

Registry holds registered channel plugins keyed by name.

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates an empty plugin registry.

func (*Registry) Get

func (r *Registry) Get(name string) ChannelPlugin

Get returns the plugin with the given name, or nil if not found.

func (*Registry) Register

func (r *Registry) Register(p ChannelPlugin)

Register adds a plugin to the registry, keyed by its Name().

Jump to

Keyboard shortcuts

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