import type { ActionListenerEvent } from './actions/index.js';
import { type AgentLike } from './facade.js';
import type { RelayMessage, RelayMessageChannelRef, RelayMessageCreatedEvent, RelayMessageReadEvent, RelayMessageSender, RelayMessageTarget, RelayMessagingEvent, RelayMessagingEventsSurface, RelayReactionEvent } from './messaging/index.js';
import type { AgentSessionEvent, AgentSessionStatus } from './session/index.js';
/** A session event tagged with the id of the agent that produced it. */
export interface SessionListenerEnvelope {
    agentId: string;
    event: AgentSessionEvent;
}
/** Wiring handed to a predicate when `relay.on(...)` subscribes it. */
export interface ListenerContext {
    events: RelayMessagingEventsSurface;
    onActionEvent(handler: (event: ActionListenerEvent) => void): () => void;
    onSessionEvent(handler: (envelope: SessionListenerEnvelope) => void): () => void;
}
export type ListenerHandler<TEvent = unknown> = (event: TEvent) => void | Promise<void>;
export interface ListenerPredicate<TEvent = unknown> {
    subscribe(context: ListenerContext, handler: ListenerHandler<TEvent>): () => void;
}
export declare class MessageCreatedPredicate implements ListenerPredicate<RelayMessageCreatedEvent> {
    private channel?;
    private mentioned?;
    in(channel: string): this;
    mentions(agent: AgentLike): this;
    subscribe(context: ListenerContext, handler: ListenerHandler<RelayMessageCreatedEvent>): () => void;
}
export declare class MessageReadPredicate implements ListenerPredicate<RelayMessageReadEvent> {
    subscribe(context: ListenerContext, handler: ListenerHandler<RelayMessageReadEvent>): () => void;
}
export declare class MessageReactedPredicate implements ListenerPredicate<RelayReactionEvent> {
    subscribe(context: ListenerContext, handler: ListenerHandler<RelayReactionEvent>): () => void;
}
export interface MessageEventBuilders {
    created(): MessageCreatedPredicate;
    read(): MessageReadPredicate;
    reacted(): MessageReactedPredicate;
}
export interface EnrichedEvents extends RelayMessagingEventsSurface {
    message: MessageEventBuilders;
}
export declare function createEnrichedEvents(base: RelayMessagingEventsSurface): EnrichedEvents;
export declare class ActionPredicate implements ListenerPredicate<ActionListenerEvent> {
    private readonly action;
    private caller?;
    private phase;
    constructor(action: string);
    calledBy(agent: AgentLike): this;
    completed(): this;
    failed(): this;
    denied(): this;
    subscribe(context: ListenerContext, handler: ListenerHandler<ActionListenerEvent>): () => void;
}
export declare class StatusPredicate implements ListenerPredicate<AgentSessionEvent> {
    private readonly agentId;
    private readonly status;
    constructor(agentId: string, status: AgentSessionStatus);
    subscribe(context: ListenerContext, handler: ListenerHandler<AgentSessionEvent>): () => void;
}
type ToolCalledEvent = Extract<AgentSessionEvent, {
    type: 'tool.called';
}>;
export declare class ToolCalledPredicate implements ListenerPredicate<ToolCalledEvent> {
    private readonly agentId;
    private readonly tool;
    private filter?;
    constructor(agentId: string, tool: string);
    where(filter: (event: ToolCalledEvent) => boolean): this;
    subscribe(context: ListenerContext, handler: ListenerHandler<ToolCalledEvent>): () => void;
}
export interface AgentStatusBuilders {
    becomes(status: AgentSessionStatus): StatusPredicate;
}
export interface AgentToolBuilders {
    called(tool: string): ToolCalledPredicate;
}
/**
 * A live handle for an agent that carries its identity plus predicate builders
 * used with `relay.on(...)`. Returned by harness `create(...)` and `relay.agent(...)`.
 */
export interface RelayAgentHandle {
    id: string;
    name: string;
    handle: string;
    token?: string;
    status: AgentStatusBuilders;
    tools: AgentToolBuilders;
}
export interface AgentHandleInput {
    id: string;
    name: string;
    handle?: string;
    token?: string;
}
/** Flat, ergonomic view of a message event's participants and location. */
export interface RelayEventEnvelope {
    from?: RelayMessageSender;
    to?: RelayMessageTarget;
    channel?: RelayMessageChannelRef;
    parent?: string;
}
export interface RelayMessageEvent {
    type: 'message.created' | 'message.updated' | 'thread.reply' | 'dm.received' | 'group_dm.received';
    message: RelayMessage;
    envelope: RelayEventEnvelope;
}
export interface RelayMessageReadEventPublic {
    type: 'message.read';
    messageId: string;
    agentName: string;
    readAt?: string;
}
export interface RelayMessageReactedEvent {
    type: 'message.reacted';
    messageId: string;
    emoji: string;
    agentName: string;
    action: 'added' | 'removed';
}
export interface RelayActionEvent {
    type: 'action.invoked' | 'action.completed' | 'action.failed' | 'action.denied';
    action: string;
    agent: ActionListenerEvent['caller'];
    input?: unknown;
    output?: unknown;
    error?: string;
    reason?: string;
    at: string;
}
export interface RelayAgentStatusEvent {
    type: 'agent.status.changed' | 'agent.status.idle' | 'agent.status.active' | 'agent.status.blocked' | 'agent.status.waiting' | 'agent.status.offline';
    agentId: string;
    status?: AgentSessionStatus;
    reason?: string;
}
export interface RelaySessionEvent {
    type: string;
    agentId: string;
    event: AgentSessionEvent;
}
/** The discriminated event object delivered to every `addListener` handler. */
export type RelayEvent = RelayMessageEvent | RelayMessageReadEventPublic | RelayMessageReactedEvent | RelayActionEvent | RelayAgentStatusEvent | RelaySessionEvent;
/** Map a raw messaging event to its public form, or `undefined` if not surfaced. */
export declare function toPublicMessagingEvent(raw: RelayMessagingEvent): RelayEvent | undefined;
/** Match a selector (`'*'`, `'message.*'`, or an exact dotted name) against an event type. */
export declare function matchesSelector(selector: string, type: string): boolean;
export interface ActionEventSource {
    onEvent?(handler: (event: ActionListenerEvent) => void): () => void;
}
export interface ListenerHub {
    readonly events: EnrichedEvents;
    on<TEvent>(predicate: ListenerPredicate<TEvent>, handler: ListenerHandler<TEvent>): () => void;
    /** Subscribe by dotted event name, `'*'`/prefix wildcard, or a predicate. */
    addListener(selector: string | ListenerPredicate, handler: ListenerHandler<RelayEvent>): () => void;
    action(name: string): ActionPredicate;
    agent(input: AgentHandleInput): RelayAgentHandle;
    /** Feed a harness session event into the hub so agent predicates can fire. */
    emitSessionEvent(agentId: string, event: AgentSessionEvent): void;
}
export declare function createListenerHub(baseEvents: RelayMessagingEventsSurface, actions: ActionEventSource): ListenerHub;
export declare function createAgentHandle(input: AgentHandleInput): RelayAgentHandle;
export {};
//# sourceMappingURL=listeners.d.ts.map