UNPKG

@mastra/core

Version:
269 lines 10.1 kB
import type { Agent } from '../agent/agent.js'; import type { AgentSignalIfIdleOptions } from '../agent/types.js'; import type { Mastra } from '../mastra/index.js'; import type { SendNotificationSignalInput } from '../notifications/types.js'; import type { InputProcessorOrWorkflow, OutputProcessorOrWorkflow } from '../processors/index.js'; /** * Identifies a specific agent thread that a signal provider targets. * * @experimental Agent signals are experimental and may change in a future release. */ export type SignalProviderTarget = { threadId: string; resourceId: string; agentId?: string; /** Options for signal delivery when the target thread is idle — forwarded to sendNotificationSignal */ ifIdle?: AgentSignalIfIdleOptions<unknown>; }; /** * A subscription that links an agent thread to an external resource * monitored by a signal provider. * * @experimental Agent signals are experimental and may change in a future release. */ export type SignalSubscription = { /** Unique identifier for the subscription */ id: string; /** The provider that owns this subscription */ providerId: string; /** The thread receiving signals */ threadId: string; /** The resource owning the thread */ resourceId: string; /** Provider-specific identifier for the external resource (e.g., "github:owner/repo#123") */ externalResourceId: string; /** When the subscription was created */ subscribedAt: Date; /** Provider-specific metadata for the subscription */ metadata: Record<string, unknown>; }; /** * Options for the handleWebhook method. * * @experimental Agent signals are experimental and may change in a future release. */ export type SignalProviderWebhookRequest = { body: unknown; headers: Record<string, string>; params?: Record<string, string>; }; /** * Abstract base for signal providers. * * A SignalProvider monitors external sources and pushes notification signals * into agent threads. It combines three capabilities: * * 1. **Subscription tracking** — built-in registry of which threads are subscribed to which external resources * 2. **External monitoring** — polling or webhook-driven event ingestion * 3. **Optional processor/tool integration** — providers can expose input/output processors and tools * * Not all signal providers are processors. A provider that only polls an API * and pushes notifications needs no processor hooks at all. Providers that * need to intercept agent execution (e.g., injecting subscription hints) can * return processors via `getInputProcessors()` / `getOutputProcessors()`. * Providers that expose agent tools (e.g., subscribe/unsubscribe commands) * can return them via `getTools()`. * * ## Usage * * ```ts * const agent = new Agent({ * signals: [new MySignalProvider()], * }); * ``` * * The Agent automatically: * - Calls `connect(this)` to establish the bidirectional link * - Registers any processors returned by `getInputProcessors()` / `getOutputProcessors()` * - Merges any tools returned by `getTools()` * - Starts polling if `pollInterval` is defined * * ## Building a Provider * * Extend this class, implement the abstract `id` field, and override * whichever hooks your provider needs: * * ```ts * class SlackSignals extends SignalProvider<'slack-signals'> { * readonly id = 'slack-signals'; * readonly pollInterval = 30_000; // poll every 30s * * async poll(subscriptions: SignalSubscription[]) { * for (const sub of subscriptions) { * // check Slack, emit notifications for changes * } * } * } * ``` * * @experimental Agent signals are experimental and may change in a future release. */ export declare abstract class SignalProvider<TId extends string = string> { #private; abstract readonly id: TId; readonly name?: string; /** * The Mastra instance this provider is registered with. * Set by the framework when the agent is registered with Mastra. */ protected mastra?: Mastra<any, any, any, any, any, any, any, any, any, any>; /** * @internal Called when the provider's agent is registered with a Mastra instance. */ __registerMastra(mastra: Mastra<any, any, any, any, any, any, any, any, any, any>): void; /** * Called by the Agent constructor to establish the bidirectional link. * Override to perform additional setup (always call `super.connect(agent)`). */ connect(agent: Agent<any, any, any, any>): void; /** * Whether this provider is already connected to an agent. * Used to skip re-wiring when an Agent is forked via `__fork()`. */ get isConnected(): boolean; /** * The connected agent. Available after `connect()` has been called. * Use this to send signals and notification signals back into agent threads. */ protected get agent(): Agent<any, any, any, any> | undefined; /** * Return input processors this provider needs registered with the agent. * Override when your provider intercepts agent input steps (e.g., injecting * subscription hints, detecting PR-related shell commands). * * @example * ```ts * getInputProcessors() { * return [this]; // when the provider itself implements processInputStep * } * ``` */ getInputProcessors?(): InputProcessorOrWorkflow[]; /** * Return output processors this provider needs registered with the agent. * Override when your provider intercepts agent output steps. */ getOutputProcessors?(): OutputProcessorOrWorkflow[]; /** * Return tools this provider exposes to the agent. * Override when your provider adds agent-callable tools (e.g., * subscribe/unsubscribe commands). * * @example * ```ts * getTools() { * return { * subscribe_pr: createTool({ ... }), * unsubscribe_pr: createTool({ ... }), * }; * } * ``` */ getTools?(): Record<string, unknown>; /** * Subscribe a thread to an external resource. * * @param target - The thread to receive signals * @param externalResourceId - Provider-specific resource identifier * (e.g., `"github:mastra-ai/mastra#123"`, `"slack:C0B01RW7A4T"`) * @param metadata - Optional provider-specific metadata for the subscription */ protected subscribe(target: SignalProviderTarget, externalResourceId: string, metadata?: Record<string, unknown>): SignalSubscription; /** * Unsubscribe a thread from an external resource. * * @returns `true` if a subscription was removed, `false` if none existed */ protected unsubscribe(target: SignalProviderTarget, externalResourceId: string): boolean; /** * Get all active subscriptions for this provider. */ protected getSubscriptions(): SignalSubscription[]; /** * Get all subscriptions for a specific external resource. * * @example * ```ts * const subs = this.getSubscriptionsForResource('github:mastra-ai/mastra#123'); * for (const sub of subs) { * await this.notify({ ... }, { resourceId: sub.resourceId, threadId: sub.threadId }); * } * ``` */ protected getSubscriptionsForResource(externalResourceId: string): SignalSubscription[]; /** * Get all subscriptions for a specific thread. */ protected getSubscriptionsForThread(target: SignalProviderTarget): SignalSubscription[]; /** * Check if a thread is subscribed to a specific external resource. */ protected hasSubscription(target: SignalProviderTarget, externalResourceId: string): boolean; /** * Remove all subscriptions for a thread. */ protected unsubscribeAll(target: SignalProviderTarget): number; /** * Total number of active subscriptions. */ protected get subscriptionCount(): number; /** * Optional poll interval in milliseconds. * When defined, the framework calls `poll()` on this interval * with all active subscriptions. * * Set to `undefined` or `0` for webhook-only providers that don't poll. */ readonly pollInterval?: number; /** * Called on each poll cycle with all active subscriptions. * Override to check external sources and emit notifications. * * @param subscriptions - All active subscriptions for this provider */ poll?(subscriptions: SignalSubscription[]): Promise<void>; /** * Start the polling timer. Called automatically by the Agent after `connect()`. * Can also be called manually to restart polling after `stopPolling()`. */ startPolling(): void; /** * Stop the polling timer. */ stopPolling(): void; /** * Handle an incoming webhook request. * Override to parse the payload, match it to subscriptions, * and emit notification signals. * * The framework routes `POST /api/signals/:providerId` to this method. */ handleWebhook?(request: SignalProviderWebhookRequest): Promise<{ status?: number; body?: unknown; }>; /** * Called after `connect()` to perform async initialization. * Override for setup that requires the agent or Mastra to be available. */ start?(): Promise<void> | void; /** * Called on shutdown. Override to clean up resources. * Default implementation stops polling and clears all subscriptions. */ stop(): void; /** * Send a notification signal to the connected agent. * Convenience wrapper around `this.agent.sendNotificationSignal()`. * * @throws If no agent is connected */ protected notify(notification: SendNotificationSignalInput, target: SignalProviderTarget): Promise<void>; } /** * Type guard to check if an object is a SignalProvider. * * @experimental Agent signals are experimental and may change in a future release. */ export declare function isSignalProvider(obj: unknown): obj is SignalProvider; //# sourceMappingURL=signal-provider.d.ts.map