SignalProvider
新增于: @mastra/core@1.39.0
用于构建 Signal Provider 的抽象基类。Signal Provider 监视外部来源(API、webhook、事件流),并通过内置订阅注册表将通知 Signal 推送至 Agent thread。
Signal Provider 默认不是处理器。需要拦截 Agent 执行的 Provider 会从 getInputProcessors() 或 getOutputProcessors() 返回处理器。暴露供 Agent 调用的 Tool 的 Provider 会从 getTools() 返回它们。
如需可直接使用的基于 webhook 的 Provider,请参阅 WebhookSignalProvider。
使用示例使用示例的直接链接
每 30 秒检查一次 API 的轮询 Provider:
import { SignalProvider } from '@mastra/core/signals'
import type { SignalSubscription } from '@mastra/core/signals'
class SlackSignals extends SignalProvider<'slack-signals'> {
readonly id = 'slack-signals'
readonly pollInterval = 30_000
async poll(subscriptions: SignalSubscription[]) {
for (const sub of subscriptions) {
const messages = await fetchSlackMessages(sub.externalResourceId)
if (messages.length > 0) {
await this.notify(
{
source: 'slack',
kind: 'new-messages',
summary: `${messages.length} new messages in ${sub.externalResourceId}`,
},
{ threadId: sub.threadId, resourceId: sub.resourceId },
)
}
}
}
}
注册到 Agent:
import { Agent } from '@mastra/core/agent'
const agent = new Agent({
id: 'agent',
signals: [new SlackSignals()],
})
Agent 调用 connect(this) 并注册 Provider 返回的所有处理器或 Tool,然后开始轮询。
构造函数参数构造函数参数的直接链接
SignalProvider 是抽象类。子类调用不带参数的 super()。
属性属性的直接链接
id:
name?:
pollInterval?:
poll()。对于仅 webhook 的 Provider,请保留为 undefined 或 0。isConnected:
connect() 后返回 true。内部用于在 Agent.__fork() 期间跳过重新连接。方法方法的直接链接
连接连接的直接链接
connect(agent)connectagent的直接链接
由 Agent 构造函数调用。建立双向链接,以便 Provider 将 Signal 发送回 Agent。可重写此方法,以在链接建立后执行额外设置。务必调用 super.connect(agent)。
class MySignals extends SignalProvider<'my-signals'> {
readonly id = 'my-signals'
override connect(agent) {
super.connect(agent)
// additional setup after agent link is established
}
}
__registerMastra(mastra)__registermastramastra的直接链接
当 Provider 的 Agent 注册到 Mastra 实例时调用。可重写此方法以访问 storage 或其他 Mastra 服务。务必调用 super.__registerMastra(mastra)。
override __registerMastra(mastra) {
super.__registerMastra(mastra)
// this.mastra is now available
}
处理器和 Tool 集成处理器和 Tool 集成的直接链接
getInputProcessors()getinputprocessors的直接链接
返回此 Provider 需要注册到 Agent 的输入处理器。当 Provider 要拦截 Agent 输入步骤时重写(例如注入上下文提示或检测 Tool 调用)。
getInputProcessors() {
return [this]
}
返回:InputProcessorOrWorkflow[]
getOutputProcessors()getoutputprocessors的直接链接
返回此 Provider 需要注册到 Agent 的输出处理器。当 Provider 要拦截 Agent 输出步骤时重写。
getOutputProcessors() {
return [this]
}
返回:OutputProcessorOrWorkflow[]
getTools()gettools的直接链接
返回此 Provider 向 Agent 暴露的 Tool。当 Provider 添加可由 Agent 调用的 Tool(如订阅或取消订阅命令)时重写。
getTools() {
return {
subscribe_pr: createTool({ /* ... */ }),
unsubscribe_pr: createTool({ /* ... */ }),
}
}
返回:Record<string, unknown>
订阅跟踪订阅跟踪的直接链接
subscribe(target, externalResourceId, metadata?)subscribetarget-externalresourceid-metadata的直接链接
为 thread 订阅外部资源。这是受保护的方法:请从 Provider 实现内部调用。
const sub = this.subscribe(
{ threadId: 'thread-1', resourceId: 'user-1' },
'github:mastra-ai/mastra#123',
{ pr: 123 },
)
返回:SignalSubscription:创建的订阅,或具有已合并 metadata 的现有订阅。
target:
threadId 和 resourceId。externalResourceId:
"github:owner/repo#123")。metadata?:
unsubscribe(target, externalResourceId)unsubscribetarget-externalresourceid的直接链接
移除订阅。
const removed = this.unsubscribe(
{ threadId: 'thread-1', resourceId: 'user-1' },
'github:mastra-ai/mastra#123',
)
返回:boolean:移除时为 true;不存在匹配订阅时为 false。
getSubscriptions()getsubscriptions的直接链接
返回此 Provider 的所有活跃订阅。
const allSubs = this.getSubscriptions()
返回:SignalSubscription[]
getSubscriptionsForResource(externalResourceId)getsubscriptionsforresourceexternalresourceid的直接链接
返回特定外部资源的所有订阅。
const subs = this.getSubscriptionsForResource('github:mastra-ai/mastra#123')
for (const sub of subs) {
await this.notify(
{ source: 'my-provider', kind: 'update', summary: 'Resource updated' },
{ threadId: sub.threadId, resourceId: sub.resourceId },
)
}
返回:SignalSubscription[]
getSubscriptionsForThread(target)getsubscriptionsforthreadtarget的直接链接
返回特定 thread 的所有订阅。
const subs = this.getSubscriptionsForThread({
threadId: 'thread-1',
resourceId: 'user-1',
})
返回:SignalSubscription[]
hasSubscription(target, externalResourceId)hassubscriptiontarget-externalresourceid的直接链接
检查订阅是否存在。
if (this.hasSubscription(target, 'github:mastra-ai/mastra#123')) {
// already subscribed
}
返回:boolean
unsubscribeAll(target)unsubscribealltarget的直接链接
移除一个 thread 的全部订阅。
const removed = this.unsubscribeAll({
threadId: 'thread-1',
resourceId: 'user-1',
})
返回:number:已移除订阅的数量。
subscriptionCountsubscriptioncount的直接链接
此 Provider 的活跃订阅总数。
if (this.subscriptionCount === 0) {
// nothing to poll
}
返回:number
轮询轮询的直接链接
poll(subscriptions)pollsubscriptions的直接链接
在每个轮询周期中使用所有活跃订阅调用。重写以检查外部来源并发出通知。框架会防止轮询周期重叠:若 poll() 调用耗时超过 pollInterval,则跳过下一周期。
async poll(subscriptions: SignalSubscription[]) {
for (const sub of subscriptions) {
const events = await checkExternalSource(sub.externalResourceId)
for (const event of events) {
await this.notify(
{ source: 'my-provider', kind: event.type, summary: event.message },
{ threadId: sub.threadId, resourceId: sub.resourceId },
)
}
}
}
startPolling()startpolling的直接链接
启动轮询计时器。由 Agent 在 connect() 后调用。具有幂等性:多次调用没有影响。
provider.startPolling()
stopPolling()stoppolling的直接链接
停止轮询计时器。
provider.stopPolling()
WebhooksWebhooks的直接链接
handleWebhook(request)handlewebhookrequest的直接链接
处理传入的 webhook 请求。重写以解析 payload 并将其与订阅匹配,然后发出通知 Signal。有关可直接使用的实现,请参阅 WebhookSignalProvider。
验证 webhook 请求后,从应用程序定义的 HTTP 端点调用此方法。
async handleWebhook(request) {
const payload = request.body as { repo: string, event: string }
const subs = this.getSubscriptionsForResource(payload.repo)
for (const sub of subs) {
await this.notify(
{ source: 'github', kind: payload.event, summary: `Event on ${payload.repo}` },
{ threadId: sub.threadId, resourceId: sub.resourceId },
)
}
return { status: 200, body: { matched: subs.length } }
}
返回:Promise<{ status?: number; body?: unknown }>
生命周期生命周期的直接链接
start()start的直接链接
在 connect() 后调用以运行异步初始化。当设置需要 Agent 或 Mastra 实例可用时重写。
async start() {
await this.loadInitialState()
}
stop()stop的直接链接
关闭时调用。默认实现会停止轮询并清除所有订阅。
provider.stop()
通知通知的直接链接
notify(notification, target)notifynotification-target的直接链接
向已连接的 Agent 发送通知 Signal。这是对 agent.sendNotificationSignal() 的受保护便捷封装。
await this.notify(
{
source: 'my-provider',
kind: 'pr-updated',
summary: 'PR #123 was updated',
priority: 'high',
payload: { prNumber: 123 },
},
{ threadId: 'thread-1', resourceId: 'user-1' },
)
notification:
source:
kind:
"pr-updated"、"new-message")。summary:
priority?:
payload?:
target:
threadId 和 resourceId。类型类型的直接链接
SignalSubscriptionsignalsubscription的直接链接
由 subscribe() 返回的订阅对象。
id:
providerId:
threadId:
resourceId:
externalResourceId:
"github:owner/repo#123")。subscribedAt:
metadata:
SignalProviderTargetsignalprovidertarget的直接链接
标识特定的 Agent thread。
threadId:
resourceId:
agentId?:
类型守卫类型守卫的直接链接
isSignalProvider(obj)issignalproviderobj的直接链接
用于检查 SignalProvider 实例的运行时检查。
import { isSignalProvider } from '@mastra/core/signals'
if (isSignalProvider(obj)) {
obj.connect(agent)
}
返回:boolean