chatnotifier

package
v0.16.0 Latest Latest
Warning

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

Go to latest
Published: May 8, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package chatnotifier provides the Session-scoped message delivery abstractions introduced by the chat-session-redesign spec. See pkg/domain/interfaces/session_notifier.go for the interface contract.

Implementations are constructed per request via Factory and passed into ChatUseCase.Execute through context (see ctx.go). There is no global registry; the Factory is the only stateful piece and it holds only shared service dependencies (repository, Slack service, etc.), never per-Session state.

This subpackage of pkg/service/notifier exists so that the new SessionNotifier implementations (SlackChatNotifier / WebNotifier / CLINotifier / NoopNotifier) do not collide in identifier space with the pre-existing alert pipeline Notifier implementations in the parent package (e.g. SlackNotifier, ConsoleNotifier for pipeline events).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FromContext

func FromContext(ctx context.Context) interfaces.SessionNotifier

FromContext retrieves the SessionNotifier stored on ctx by WithNotifier, falling back to NoopNotifier when none is set. Callers may safely call methods on the result without nil checks.

func WithNotifier

WithNotifier attaches n to ctx so that downstream code can retrieve it via FromContext. The returned context carries a single SessionNotifier reference; there is no global registry keyed by Session ID.

This helper is the *only* sanctioned channel for passing a SessionNotifier through a request. Per the chat-session-redesign multi-instance rule, we never place a package-scope map<SessionID, Notifier>; that would break the moment a second instance handles the response.

Types

type CLINotifier

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

CLINotifier delivers messages to a writer (typically os.Stdout) and persists them as Messages in the current CLI Session.

func NewCLINotifier

func NewCLINotifier(repo interfaces.Repository, sess *session.Session, turnID *types.TurnID, w io.Writer) *CLINotifier

NewCLINotifier constructs a CLINotifier bound to sess + turnID. turnID may be nil for messages that are not tied to a Turn, though in CLI mode every invocation typically carries a Turn.

func (*CLINotifier) Notify

func (c *CLINotifier) Notify(ctx context.Context, content string) error

func (*CLINotifier) NotifyUser

func (c *CLINotifier) NotifyUser(ctx context.Context, content string, author *session.Author) error

func (*CLINotifier) Plan

func (c *CLINotifier) Plan(ctx context.Context, content string) error

func (*CLINotifier) Trace

func (c *CLINotifier) Trace(ctx context.Context, content string) error

func (*CLINotifier) Warn

func (c *CLINotifier) Warn(ctx context.Context, content string) error

type Factory

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

Factory constructs SessionNotifier implementations per-request. It carries only shared service dependencies (repository, Slack service, web event publisher, CLI writer) and holds no per-Session state. A Factory is therefore safe to share across goroutines and across Sessions.

Factories live for the lifetime of the process; the Session-specific binding happens inside FromSession which returns a fresh notifier each call.

func NewFactory

func NewFactory(repo interfaces.Repository, opts ...FactoryOption) *Factory

NewFactory constructs a Factory. repo is required.

func (*Factory) FromSession

func (f *Factory) FromSession(sess *session.Session, turnID *types.TurnID) interfaces.SessionNotifier

FromSession returns a SessionNotifier appropriate for sess.Source. turnID is the Turn that new Messages should be attributed to; it may be nil for messages that do not belong to a Turn (e.g. non-mention Slack thread messages).

The returned notifier is owned by the caller and safe to pass through ctx via WithNotifier. It should not be reused across different Sessions.

type FactoryOption

type FactoryOption func(*Factory)

FactoryOption configures optional dependencies on a Factory.

func WithCLIWriter

func WithCLIWriter(w io.Writer) FactoryOption

WithCLIWriter provides the writer used by CLINotifier (defaults to os.Stdout).

func WithSlackService

func WithSlackService(s SlackThreadFactory) FactoryOption

WithSlackService provides the Slack service used to construct SlackChatNotifier instances. Without it, Slack Sessions fall back to NoopNotifier.

func WithWebPublisher

func WithWebPublisher(p interfaces.WebEventPublisher) FactoryOption

WithWebPublisher provides the WebSocket Hub publisher used to construct WebNotifier instances. Without it, Web Sessions fall back to NoopNotifier (Messages are still persisted via the caller, but no realtime push happens).

type NoopNotifier

type NoopNotifier struct{}

NoopNotifier is a SessionNotifier that does nothing. It satisfies the interface for cases where no Session has been wired up yet (ticketless bootstrap, tests, etc.).

func (NoopNotifier) Notify

func (NoopNotifier) NotifyUser

func (NoopNotifier) Plan

func (NoopNotifier) Trace

func (NoopNotifier) Warn

type SlackChatNotifier

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

SlackChatNotifier persists Messages and mirrors AI-produced content into the bound Slack thread. Incoming user Messages (type=user) are persisted but NOT posted back to Slack; the user's own message is already visible in the thread by construction.

func NewSlackChatNotifier

func NewSlackChatNotifier(
	repo interfaces.Repository,
	thread interfaces.SlackThreadService,
	sess *session.Session,
	turnID *types.TurnID,
) *SlackChatNotifier

NewSlackChatNotifier constructs a SlackChatNotifier. thread may be nil if the Session has no bound Slack thread, in which case Slack delivery is silently skipped (Message persistence still happens).

func (*SlackChatNotifier) Notify

func (s *SlackChatNotifier) Notify(ctx context.Context, content string) error

func (*SlackChatNotifier) NotifyUser

func (s *SlackChatNotifier) NotifyUser(ctx context.Context, content string, author *session.Author) error

NotifyUser records a user-authored Message. The originating Slack message is already visible in the thread (the user sent it), so no post-back is issued; we only persist for Session history.

func (*SlackChatNotifier) Plan

func (s *SlackChatNotifier) Plan(ctx context.Context, content string) error

func (*SlackChatNotifier) Trace

func (s *SlackChatNotifier) Trace(ctx context.Context, content string) error

func (*SlackChatNotifier) Warn

func (s *SlackChatNotifier) Warn(ctx context.Context, content string) error

type SlackThreadFactory

type SlackThreadFactory interface {
	NewThread(thread slackModel.Thread) interfaces.SlackThreadService
}

SlackThreadFactory is the minimal surface the chatnotifier Factory needs from the Slack service: resolve a Thread reference into a SlackThreadService. The concrete implementation lives in pkg/service/slack.

type WebNotifier

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

WebNotifier persists Messages and pushes a deterministic JSON event to the WebSocket Hub for clients viewing the owning Ticket.

func NewWebNotifier

func NewWebNotifier(
	repo interfaces.Repository,
	publisher interfaces.WebEventPublisher,
	sess *session.Session,
	turnID *types.TurnID,
) *WebNotifier

NewWebNotifier constructs a WebNotifier bound to sess + turnID. publisher must be non-nil; it is typically the hub bridge registered at server startup.

func (*WebNotifier) Notify

func (w *WebNotifier) Notify(ctx context.Context, content string) error

func (*WebNotifier) NotifyUser

func (w *WebNotifier) NotifyUser(ctx context.Context, content string, author *session.Author) error

func (*WebNotifier) Plan

func (w *WebNotifier) Plan(ctx context.Context, content string) error

func (*WebNotifier) Trace

func (w *WebNotifier) Trace(ctx context.Context, content string) error

func (*WebNotifier) Warn

func (w *WebNotifier) Warn(ctx context.Context, content string) error

Jump to

Keyboard shortcuts

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