@mastra/core
Version:
137 lines • 6.45 kB
TypeScript
import type { Message, Thread } from 'chat';
import type { Agent } from '../agent/agent.js';
import type { MastraProviderMetadata } from '../agent/message-list/state/types.js';
import type { AgentSignalContents } from '../agent/signals.js';
import type { AgentController } from '../agent-controller/agent-controller.js';
import type { Session } from '../agent-controller/session.js';
import type { Mastra } from '../mastra/index.js';
import type { StorageThreadType } from '../memory/types.js';
import type { RequestContext } from '../request-context/index.js';
import { AgentChannels } from './agent-channels.js';
import type { ChannelConfig } from './types.js';
/** Configuration for {@link AgentControllerChannels}. Same shape as agent channels. */
export type AgentControllerChannelsConfig = ChannelConfig;
/**
* Runs an AgentController inside chat channels (Slack, Discord, ...).
*
* Extends {@link AgentChannels} so all inbound machinery (thread mapping,
* history, attachments, event context) and all outbound rendering
* (`ChatChannelOutputProcessor` with native streaming, tool cards, typing
* status) are reused unchanged. Only the dispatch seams differ: instead of
* routing into a bare agent, inbound messages route into a controller
* `Session` — one durable session per chat thread, keyed by the mapped
* Mastra thread's `resourceId`.
*
* V1 targets long-lived servers: controller sessions are in-memory objects
* and do not survive process restarts.
*/
export declare class AgentControllerChannels extends AgentChannels {
private controller;
/**
* Session resourceIds whose adapter can't render approval buttons, so their
* runs must auto-approve tools (`requireToolApproval: false`) instead of
* parking forever on an approval nobody can answer. Kept outside session
* state on purpose: state is validated against the controller's
* `stateSchema`, which would strip (or reject) an injected flag. Refreshed
* on every inbound message; in-memory only, matching the v1 long-lived
* server scope.
*/
private autoApproveResourceIds;
/** @internal Called by AgentController's constructor to bind itself. */
__setController(controller: AgentController<any>): void;
/**
* @internal Consulted by the controller's run-option builder: `true` when
* the session's channel adapter can't render approval buttons and tool
* calls must auto-approve (the session-side equivalent of the base agent
* path's `autoResumeSuspendedTools`).
*/
__isAutoApproveResource(resourceId: string): boolean;
/**
* @internal No-op override. The controller attaches this instance to its
* mode agents via `Agent.setChannels`, which calls `__setAgent(agent)` —
* with multiple mode agents the last one would win. Every `this.agent` use
* is overridden in this subclass, so keep the base field unset rather than
* holding a misleading ref.
*/
__setAgent(_agent: Agent<any, any, any, any>): void;
protected getOwnerId(): string | null;
protected getWebhookBasePath(): string;
protected getMastra(): Mastra | undefined;
/**
* One session per chat thread: unless the user supplied a custom
* `resolveResourceId`, key new Mastra threads (and therefore controller
* sessions) off the platform + external thread id.
*/
protected resolveChannelResourceId(args: {
platform: string;
chatThread: Thread;
message: Message;
defaultResourceId: string;
}): string | (() => string | Promise<string>);
/**
* Route an inbound chat message into the controller session bound to this
* chat thread. Output renders back to the platform through the channels
* output processor: the `requestContext` built by the base class (carrying
* the channel context and render context) flows through the session into
* the run.
*/
protected dispatchInboundMessage(args: {
signalContents: AgentSignalContents;
attributes: Record<string, string | undefined>;
providerOptions: MastraProviderMetadata;
requestContext: RequestContext;
thread: StorageThreadType;
memory: {
thread: string;
resource: string;
};
autoResumeSuspendedTools: true | undefined;
}): Promise<void>;
/**
* Resolve an approval-card "approve" action against the controller session's
* parked tool-approval gate. The run engine — awaiting the gate inside its
* stream-consumer loop — performs the actual resume itself and keeps
* consuming, so the continuation renders through the output processor.
*/
protected dispatchApproval(args: {
runId: string;
toolCallId: string;
requestContext: RequestContext;
memory: {
thread: string;
resource: string;
};
}): Promise<void>;
/**
* Resolve an approval-card "deny" action against the controller session's
* parked tool-approval gate (see {@link dispatchApproval}).
*/
protected dispatchDecline(args: {
runId: string;
toolCallId: string;
requestContext: RequestContext;
memory: {
thread: string;
resource: string;
};
}): Promise<void>;
/**
* Shared approve/decline path. Never calls the session's internal
* `approveToolCall`/`declineToolCall` executors directly — the engine parked
* at the gate owns the resume. `respondToToolApproval` is a silent no-op
* when nothing is armed or the toolCallId mismatches, so staleness is
* pre-checked explicitly (an armed gate does not survive process restarts,
* so restart-recovered approvals are always stale — consistent with the
* v1 long-lived-server scope).
*/
private respondToSessionApproval;
/**
* Get-or-create the durable controller session for a mapped channel thread
* and bind it to that thread. Keyed off the thread's own `resourceId` so
* pre-existing threads (custom resolveResourceId, or created before this
* feature) always pass the session's thread-ownership check.
*/
protected getSessionForThread(thread: Pick<StorageThreadType, 'id' | 'resourceId'>, requestContext?: RequestContext): Promise<Session<any>>;
private requireController;
}
//# sourceMappingURL=agent-controller-channels.d.ts.map