{"version":3,"sources":["../src/signals/signal-provider.ts","../src/signals/webhook-signal-provider.ts"],"names":[],"mappings":"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","file":"chunk-Y7R26VZI.cjs","sourcesContent":["import type { Agent } from '../agent/agent';\nimport type { Mastra } from '../mastra';\nimport type { SendNotificationSignalInput } from '../notifications/types';\nimport type { InputProcessorOrWorkflow, OutputProcessorOrWorkflow } from '../processors';\n\n/**\n * Identifies a specific agent thread that a signal provider targets.\n *\n * @experimental Agent signals are experimental and may change in a future release.\n */\nexport type SignalProviderTarget = {\n  threadId: string;\n  resourceId: string;\n  agentId?: string;\n};\n\n/**\n * A subscription that links an agent thread to an external resource\n * monitored by a signal provider.\n *\n * @experimental Agent signals are experimental and may change in a future release.\n */\nexport type SignalSubscription = {\n  /** Unique identifier for the subscription */\n  id: string;\n  /** The provider that owns this subscription */\n  providerId: string;\n  /** The thread receiving signals */\n  threadId: string;\n  /** The resource owning the thread */\n  resourceId: string;\n  /** Provider-specific identifier for the external resource (e.g., \"github:owner/repo#123\") */\n  externalResourceId: string;\n  /** When the subscription was created */\n  subscribedAt: Date;\n  /** Provider-specific metadata for the subscription */\n  metadata: Record<string, unknown>;\n};\n\n/**\n * Options for the handleWebhook method.\n *\n * @experimental Agent signals are experimental and may change in a future release.\n */\nexport type SignalProviderWebhookRequest = {\n  body: unknown;\n  headers: Record<string, string>;\n  params?: Record<string, string>;\n};\n\n/**\n * Abstract base for signal providers.\n *\n * A SignalProvider monitors external sources and pushes notification signals\n * into agent threads. It combines three capabilities:\n *\n * 1. **Subscription tracking** — built-in registry of which threads are subscribed to which external resources\n * 2. **External monitoring** — polling or webhook-driven event ingestion\n * 3. **Optional processor/tool integration** — providers can expose input/output processors and tools\n *\n * Not all signal providers are processors. A provider that only polls an API\n * and pushes notifications needs no processor hooks at all. Providers that\n * need to intercept agent execution (e.g., injecting subscription hints) can\n * return processors via `getInputProcessors()` / `getOutputProcessors()`.\n * Providers that expose agent tools (e.g., subscribe/unsubscribe commands)\n * can return them via `getTools()`.\n *\n * ## Usage\n *\n * ```ts\n * const agent = new Agent({\n *   signals: [new MySignalProvider()],\n * });\n * ```\n *\n * The Agent automatically:\n * - Calls `connect(this)` to establish the bidirectional link\n * - Registers any processors returned by `getInputProcessors()` / `getOutputProcessors()`\n * - Merges any tools returned by `getTools()`\n * - Starts polling if `pollInterval` is defined\n *\n * ## Building a Provider\n *\n * Extend this class, implement the abstract `id` field, and override\n * whichever hooks your provider needs:\n *\n * ```ts\n * class SlackSignals extends SignalProvider<'slack-signals'> {\n *   readonly id = 'slack-signals';\n *   readonly pollInterval = 30_000; // poll every 30s\n *\n *   async poll(subscriptions: SignalSubscription[]) {\n *     for (const sub of subscriptions) {\n *       // check Slack, emit notifications for changes\n *     }\n *   }\n * }\n * ```\n *\n * @experimental Agent signals are experimental and may change in a future release.\n */\nexport abstract class SignalProvider<TId extends string = string> {\n  abstract readonly id: TId;\n  readonly name?: string;\n\n  /**\n   * The Mastra instance this provider is registered with.\n   * Set by the framework when the agent is registered with Mastra.\n   */\n  protected mastra?: Mastra<any, any, any, any, any, any, any, any, any, any>;\n\n  /**\n   * @internal Called when the provider's agent is registered with a Mastra instance.\n   */\n  __registerMastra(mastra: Mastra<any, any, any, any, any, any, any, any, any, any>): void {\n    this.mastra = mastra;\n  }\n\n  /**\n   * The agent this provider is connected to.\n   * Set automatically when passed to `Agent({ signals: [...] })`.\n   */\n  #connectedAgent?: Agent<any, any, any, any>;\n\n  /**\n   * In-memory subscription registry.\n   * Key: `${resourceId}:${threadId}:${externalResourceId}`\n   */\n  readonly #subscriptions = new Map<string, SignalSubscription>();\n\n  /**\n   * Index: externalResourceId → set of subscription keys\n   */\n  readonly #subscriptionsByResource = new Map<string, Set<string>>();\n\n  /**\n   * Index: `${resourceId}:${threadId}` → set of subscription keys\n   */\n  readonly #subscriptionsByThread = new Map<string, Set<string>>();\n\n  /** Active polling timer, if any */\n  #pollTimer?: ReturnType<typeof setInterval>;\n\n  /** Guard to prevent overlapping poll cycles */\n  #isPollRunning = false;\n\n  // ── Connection ──────────────────────────────────────────────────────\n\n  /**\n   * Called by the Agent constructor to establish the bidirectional link.\n   * Override to perform additional setup (always call `super.connect(agent)`).\n   */\n  connect(agent: Agent<any, any, any, any>): void {\n    this.#connectedAgent = agent;\n  }\n\n  /**\n   * Whether this provider is already connected to an agent.\n   * Used to skip re-wiring when an Agent is forked via `__fork()`.\n   */\n  get isConnected(): boolean {\n    return this.#connectedAgent !== undefined;\n  }\n\n  /**\n   * The connected agent. Available after `connect()` has been called.\n   * Use this to send signals and notification signals back into agent threads.\n   */\n  protected get agent(): Agent<any, any, any, any> | undefined {\n    return this.#connectedAgent;\n  }\n\n  // ── Processors & Tools ─────────────────────────────────────────────\n\n  /**\n   * Return input processors this provider needs registered with the agent.\n   * Override when your provider intercepts agent input steps (e.g., injecting\n   * subscription hints, detecting PR-related shell commands).\n   *\n   * @example\n   * ```ts\n   * getInputProcessors() {\n   *   return [this]; // when the provider itself implements processInputStep\n   * }\n   * ```\n   */\n  getInputProcessors?(): InputProcessorOrWorkflow[];\n\n  /**\n   * Return output processors this provider needs registered with the agent.\n   * Override when your provider intercepts agent output steps.\n   */\n  getOutputProcessors?(): OutputProcessorOrWorkflow[];\n\n  /**\n   * Return tools this provider exposes to the agent.\n   * Override when your provider adds agent-callable tools (e.g.,\n   * subscribe/unsubscribe commands).\n   *\n   * @example\n   * ```ts\n   * getTools() {\n   *   return {\n   *     subscribe_pr: createTool({ ... }),\n   *     unsubscribe_pr: createTool({ ... }),\n   *   };\n   * }\n   * ```\n   */\n  getTools?(): Record<string, unknown>;\n\n  // ── Subscription tracking ──────────────────────────────────────────\n\n  /**\n   * Subscribe a thread to an external resource.\n   *\n   * @param target - The thread to receive signals\n   * @param externalResourceId - Provider-specific resource identifier\n   *   (e.g., `\"github:mastra-ai/mastra#123\"`, `\"slack:C0B01RW7A4T\"`)\n   * @param metadata - Optional provider-specific metadata for the subscription\n   */\n  protected subscribe(\n    target: SignalProviderTarget,\n    externalResourceId: string,\n    metadata: Record<string, unknown> = {},\n  ): SignalSubscription {\n    const key = this.#subscriptionKey(target, externalResourceId);\n    const existing = this.#subscriptions.get(key);\n    if (existing) {\n      existing.metadata = { ...existing.metadata, ...metadata };\n      return existing;\n    }\n\n    const subscription: SignalSubscription = {\n      id: crypto.randomUUID(),\n      providerId: this.id,\n      threadId: target.threadId,\n      resourceId: target.resourceId,\n      externalResourceId,\n      subscribedAt: new Date(),\n      metadata,\n    };\n\n    this.#subscriptions.set(key, subscription);\n\n    // Update resource index\n    let resourceSet = this.#subscriptionsByResource.get(externalResourceId);\n    if (!resourceSet) {\n      resourceSet = new Set();\n      this.#subscriptionsByResource.set(externalResourceId, resourceSet);\n    }\n    resourceSet.add(key);\n\n    // Update thread index\n    const threadKey = this.#threadKey(target);\n    let threadSet = this.#subscriptionsByThread.get(threadKey);\n    if (!threadSet) {\n      threadSet = new Set();\n      this.#subscriptionsByThread.set(threadKey, threadSet);\n    }\n    threadSet.add(key);\n\n    return subscription;\n  }\n\n  /**\n   * Unsubscribe a thread from an external resource.\n   *\n   * @returns `true` if a subscription was removed, `false` if none existed\n   */\n  protected unsubscribe(target: SignalProviderTarget, externalResourceId: string): boolean {\n    const key = this.#subscriptionKey(target, externalResourceId);\n    const subscription = this.#subscriptions.get(key);\n    if (!subscription) return false;\n\n    this.#subscriptions.delete(key);\n\n    // Clean up resource index\n    const resourceSet = this.#subscriptionsByResource.get(externalResourceId);\n    if (resourceSet) {\n      resourceSet.delete(key);\n      if (resourceSet.size === 0) this.#subscriptionsByResource.delete(externalResourceId);\n    }\n\n    // Clean up thread index\n    const threadKey = this.#threadKey(target);\n    const threadSet = this.#subscriptionsByThread.get(threadKey);\n    if (threadSet) {\n      threadSet.delete(key);\n      if (threadSet.size === 0) this.#subscriptionsByThread.delete(threadKey);\n    }\n\n    return true;\n  }\n\n  /**\n   * Get all active subscriptions for this provider.\n   */\n  protected getSubscriptions(): SignalSubscription[] {\n    return [...this.#subscriptions.values()];\n  }\n\n  /**\n   * Get all subscriptions for a specific external resource.\n   *\n   * @example\n   * ```ts\n   * const subs = this.getSubscriptionsForResource('github:mastra-ai/mastra#123');\n   * for (const sub of subs) {\n   *   await this.notify({ ... }, { resourceId: sub.resourceId, threadId: sub.threadId });\n   * }\n   * ```\n   */\n  protected getSubscriptionsForResource(externalResourceId: string): SignalSubscription[] {\n    const keys = this.#subscriptionsByResource.get(externalResourceId);\n    if (!keys) return [];\n    return [...keys].map(key => this.#subscriptions.get(key)!).filter(Boolean);\n  }\n\n  /**\n   * Get all subscriptions for a specific thread.\n   */\n  protected getSubscriptionsForThread(target: SignalProviderTarget): SignalSubscription[] {\n    const threadKey = this.#threadKey(target);\n    const keys = this.#subscriptionsByThread.get(threadKey);\n    if (!keys) return [];\n    return [...keys].map(key => this.#subscriptions.get(key)!).filter(Boolean);\n  }\n\n  /**\n   * Check if a thread is subscribed to a specific external resource.\n   */\n  protected hasSubscription(target: SignalProviderTarget, externalResourceId: string): boolean {\n    return this.#subscriptions.has(this.#subscriptionKey(target, externalResourceId));\n  }\n\n  /**\n   * Remove all subscriptions for a thread.\n   */\n  protected unsubscribeAll(target: SignalProviderTarget): number {\n    const threadSubscriptions = this.getSubscriptionsForThread(target);\n    let removed = 0;\n    for (const sub of threadSubscriptions) {\n      if (this.unsubscribe(target, sub.externalResourceId)) removed++;\n    }\n    return removed;\n  }\n\n  /**\n   * Total number of active subscriptions.\n   */\n  protected get subscriptionCount(): number {\n    return this.#subscriptions.size;\n  }\n\n  // ── Polling ────────────────────────────────────────────────────────\n\n  /**\n   * Optional poll interval in milliseconds.\n   * When defined, the framework calls `poll()` on this interval\n   * with all active subscriptions.\n   *\n   * Set to `undefined` or `0` for webhook-only providers that don't poll.\n   */\n  readonly pollInterval?: number;\n\n  /**\n   * Called on each poll cycle with all active subscriptions.\n   * Override to check external sources and emit notifications.\n   *\n   * @param subscriptions - All active subscriptions for this provider\n   */\n  poll?(subscriptions: SignalSubscription[]): Promise<void>;\n\n  /**\n   * Start the polling timer. Called automatically by the Agent after `connect()`.\n   * Can also be called manually to restart polling after `stopPolling()`.\n   */\n  startPolling(): void {\n    if (this.#pollTimer) return;\n    const interval = this.pollInterval;\n    if (!interval || interval <= 0 || typeof this.poll !== 'function') return;\n\n    this.#pollTimer = setInterval(() => {\n      if (this.#isPollRunning) return;\n      const subscriptions = this.getSubscriptions();\n      if (subscriptions.length === 0) return;\n      this.#isPollRunning = true;\n      void Promise.resolve(this.poll!(subscriptions))\n        .catch(error => {\n          console.warn(`[${this.id}] poll failed:`, error);\n        })\n        .finally(() => {\n          this.#isPollRunning = false;\n        });\n    }, interval);\n\n    // Don't let the timer keep the process alive\n    this.#pollTimer.unref?.();\n  }\n\n  /**\n   * Stop the polling timer.\n   */\n  stopPolling(): void {\n    if (this.#pollTimer) {\n      clearInterval(this.#pollTimer);\n      this.#pollTimer = undefined;\n    }\n  }\n\n  // ── Webhook ────────────────────────────────────────────────────────\n\n  /**\n   * Handle an incoming webhook request.\n   * Override to parse the payload, match it to subscriptions,\n   * and emit notification signals.\n   *\n   * The framework routes `POST /api/signals/:providerId` to this method.\n   */\n  handleWebhook?(request: SignalProviderWebhookRequest): Promise<{ status?: number; body?: unknown }>;\n\n  // ── Lifecycle ──────────────────────────────────────────────────────\n\n  /**\n   * Called after `connect()` to perform async initialization.\n   * Override for setup that requires the agent or Mastra to be available.\n   */\n  start?(): Promise<void> | void;\n\n  /**\n   * Called on shutdown. Override to clean up resources.\n   * Default implementation stops polling and clears all subscriptions.\n   */\n  stop(): void {\n    this.stopPolling();\n    this.#subscriptions.clear();\n    this.#subscriptionsByResource.clear();\n    this.#subscriptionsByThread.clear();\n  }\n\n  // ── Convenience ────────────────────────────────────────────────────\n\n  /**\n   * Send a notification signal to the connected agent.\n   * Convenience wrapper around `this.agent.sendNotificationSignal()`.\n   *\n   * @throws If no agent is connected\n   */\n  protected async notify(notification: SendNotificationSignalInput, target: SignalProviderTarget): Promise<void> {\n    const agent = this.#connectedAgent;\n    if (!agent) {\n      throw new Error(\n        `[${this.id}] Cannot send notification: no agent connected. Was this provider passed to Agent({ signals: [...] })?`,\n      );\n    }\n\n    await agent.sendNotificationSignal(notification, {\n      resourceId: target.resourceId,\n      threadId: target.threadId,\n    });\n  }\n\n  // ── Internal ───────────────────────────────────────────────────────\n\n  #subscriptionKey(target: SignalProviderTarget, externalResourceId: string): string {\n    return `${target.resourceId}:${target.threadId}:${externalResourceId}`;\n  }\n\n  #threadKey(target: SignalProviderTarget): string {\n    return `${target.resourceId}:${target.threadId}`;\n  }\n}\n\n/**\n * Type guard to check if an object is a SignalProvider.\n *\n * @experimental Agent signals are experimental and may change in a future release.\n */\nexport function isSignalProvider(obj: unknown): obj is SignalProvider {\n  return obj instanceof SignalProvider;\n}\n","import type { SendNotificationSignalInput } from '../notifications/types';\nimport { SignalProvider } from './signal-provider';\nimport type { SignalProviderTarget, SignalProviderWebhookRequest, SignalSubscription } from './signal-provider';\n\n/**\n * Configuration for the webhook signal provider.\n *\n * @experimental Agent signals are experimental and may change in a future release.\n */\nexport type WebhookSignalProviderOptions = {\n  /**\n   * Unique identifier for the provider instance.\n   * @default 'webhook-signals'\n   */\n  id?: string;\n\n  /**\n   * Human-readable name.\n   * @default 'Webhook Signals'\n   */\n  name?: string;\n\n  /**\n   * Optional function to extract a matching key from an incoming webhook payload.\n   * The returned string is matched against `externalResourceId` in subscriptions.\n   *\n   * @default Returns `payload.resource` or `payload.externalResourceId` if present.\n   */\n  extractResourceId?: (payload: unknown) => string | string[] | undefined;\n\n  /**\n   * Optional function to build the notification from a webhook payload.\n   * When not provided, a default notification is built from the payload.\n   */\n  buildNotification?: (payload: unknown, subscription: SignalSubscription) => SendNotificationSignalInput;\n};\n\n/**\n * A generic webhook-based signal provider.\n *\n * Receives external events via HTTP webhooks and routes them to\n * subscribed agent threads as notification signals.\n *\n * ## Usage\n *\n * ```ts\n * const webhooks = new WebhookSignalProvider({\n *   extractResourceId: (payload) => (payload as any).repository,\n *   buildNotification: (payload, sub) => ({\n *     source: 'ci',\n *     kind: 'build-status',\n *     priority: 'medium',\n *     summary: `Build ${(payload as any).status} for ${sub.externalResourceId}`,\n *   }),\n * });\n *\n * const agent = new Agent({\n *   signals: [webhooks],\n * });\n *\n * // Subscribe a thread to a resource\n * webhooks.subscribeThread(\n *   { threadId: 'thread-1', resourceId: 'user-1' },\n *   'my-org/my-repo',\n * );\n *\n * // Later, when a webhook fires:\n * await webhooks.handleWebhook({\n *   body: { repository: 'my-org/my-repo', status: 'failed' },\n *   headers: {},\n * });\n * ```\n *\n * @experimental Agent signals are experimental and may change in a future release.\n */\nexport class WebhookSignalProvider extends SignalProvider<string> {\n  readonly id: string;\n  readonly name: string;\n  readonly #options: WebhookSignalProviderOptions;\n\n  constructor(options: WebhookSignalProviderOptions = {}) {\n    super();\n    this.id = options.id ?? 'webhook-signals';\n    this.name = options.name ?? 'Webhook Signals';\n    this.#options = options;\n  }\n\n  // ── Static signal factories ────────────────────────────────────────\n\n  /**\n   * Create signal inputs for subscribing/unsubscribing threads via signals.\n   */\n  static signals = {\n    subscribe(resource: string): {\n      type: 'reactive';\n      tagName: string;\n      contents: string;\n      attributes: { resource: string };\n    } {\n      return {\n        type: 'reactive',\n        tagName: 'webhook-subscribe',\n        contents: `Subscribe to webhook resource: ${resource}`,\n        attributes: { resource },\n      };\n    },\n\n    unsubscribe(resource: string): {\n      type: 'reactive';\n      tagName: string;\n      contents: string;\n      attributes: { resource: string };\n    } {\n      return {\n        type: 'reactive',\n        tagName: 'webhook-unsubscribe',\n        contents: `Unsubscribe from webhook resource: ${resource}`,\n        attributes: { resource },\n      };\n    },\n  };\n\n  // ── Public API ─────────────────────────────────────────────────────\n\n  /**\n   * Programmatically subscribe a thread to an external resource.\n   */\n  subscribeThread(\n    target: SignalProviderTarget,\n    externalResourceId: string,\n    metadata?: Record<string, unknown>,\n  ): SignalSubscription {\n    return this.subscribe(target, externalResourceId, metadata);\n  }\n\n  /**\n   * Programmatically unsubscribe a thread from an external resource.\n   */\n  unsubscribeThread(target: SignalProviderTarget, externalResourceId: string): boolean {\n    return this.unsubscribe(target, externalResourceId);\n  }\n\n  // ── Webhook handling ───────────────────────────────────────────────\n\n  /**\n   * Handle an incoming webhook. Matches the payload against subscriptions\n   * and emits notification signals to matching threads.\n   */\n  async handleWebhook(request: SignalProviderWebhookRequest): Promise<{ status?: number; body?: unknown }> {\n    const payload = request.body;\n    const resourceIds = [...new Set(this.#extractResourceIds(payload))];\n\n    if (resourceIds.length === 0) {\n      return { status: 200, body: { matched: 0 } };\n    }\n\n    let matched = 0;\n    for (const resourceId of resourceIds) {\n      const subscriptions = this.getSubscriptionsForResource(resourceId);\n      for (const subscription of subscriptions) {\n        const notification = this.#buildNotification(payload, subscription);\n        try {\n          await this.notify(notification, {\n            threadId: subscription.threadId,\n            resourceId: subscription.resourceId,\n          });\n          matched++;\n        } catch (error) {\n          console.warn(`[${this.id}] Failed to notify thread ${subscription.threadId}:`, error);\n        }\n      }\n    }\n\n    return { status: 200, body: { matched } };\n  }\n\n  // ── Internal ───────────────────────────────────────────────────────\n\n  #extractResourceIds(payload: unknown): string[] {\n    if (this.#options.extractResourceId) {\n      const result = this.#options.extractResourceId(payload);\n      if (!result) return [];\n      return Array.isArray(result) ? result : [result];\n    }\n\n    // Default: look for common payload shapes\n    if (payload && typeof payload === 'object') {\n      const obj = payload as Record<string, unknown>;\n      if (typeof obj.resource === 'string') return [obj.resource];\n      if (typeof obj.externalResourceId === 'string') return [obj.externalResourceId];\n    }\n\n    return [];\n  }\n\n  #buildNotification(payload: unknown, subscription: SignalSubscription): SendNotificationSignalInput {\n    if (this.#options.buildNotification) {\n      return this.#options.buildNotification(payload, subscription);\n    }\n\n    return {\n      source: this.id,\n      kind: 'webhook-event',\n      priority: 'medium',\n      summary: `Webhook event for ${subscription.externalResourceId}`,\n      payload,\n      dedupeKey: `${this.id}:${subscription.externalResourceId}:${Date.now()}`,\n      coalesceKey: `${this.id}:${subscription.externalResourceId}`,\n    };\n  }\n}\n"]}