eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
165 lines (164 loc) • 9.63 kB
TypeScript
import type { TeamsInstrumentationMetadata } from "#public/channels/teams/index.js";
import type { SessionAuthContext } from "#channel/types.js";
import type { SessionContext } from "#public/definitions/callback-context.js";
import type { ChannelSessionOps } from "#public/definitions/defineChannel.js";
import type { HandleMessageStreamEvent } from "#protocol/message.js";
import { type TeamsFilesConfig } from "#public/channels/teams/attachments.js";
import { type TeamsApiOptions, type TeamsApiResponse, type TeamsChannelAccount, type TeamsCredentials, type TeamsMention, type TeamsMessageBody, type TeamsOutboundActivity, type TeamsPostedActivity } from "#public/channels/teams/api.js";
import { type TeamsInvokeActivity, type TeamsMessageActivity } from "#public/channels/teams/inbound.js";
import { type TeamsWebhookVerifier } from "#public/channels/teams/verify.js";
import { type JsonObject } from "#shared/json.js";
import { type Channel } from "#public/definitions/defineChannel.js";
type EventData<T extends HandleMessageStreamEvent["type"]> = Extract<HandleMessageStreamEvent, {
type: T;
}> extends {
data: infer D;
} ? D : undefined;
/** Pre-dispatch Teams context passed to inbound message and invoke hooks. */
export interface TeamsContext {
readonly teams: TeamsHandle;
readonly thread: TeamsThread;
}
/** Channel-owned Teams context returned by `context()`. */
export interface TeamsChannelContext extends TeamsContext {
readonly adaptiveCardVersion: string;
state: TeamsChannelState;
}
/** Event-handler Teams context, including session operations. */
export interface TeamsEventContext extends TeamsChannelContext, ChannelSessionOps {
}
/** JSON-serializable Teams channel state. */
export interface TeamsChannelState {
/** Bot account captured from the inbound activity recipient. */
bot: TeamsChannelAccount | null;
channelId: string | null;
conversationId: string | null;
/** Teams conversation type (`personal`, `groupChat`, `channel`, or platform value). */
conversationType: string | null;
/** Activity id used for thread replies in channel/group contexts. */
replyToActivityId: string | null;
serviceUrl: string | null;
teamId: string | null;
tenantId: string | null;
/** User account that triggered the latest turn/session. */
triggeringUser: TeamsChannelAccount | null;
/** Activity id for the default connection-auth card, when posted. */
pendingAuthActivityId?: string | null;
}
/** Teams channel credentials. */
export interface TeamsChannelCredentials extends TeamsCredentials {
/** Custom inbound webhook verifier. When supplied, replaces Bot Connector JWT validation. */
readonly webhookVerifier?: TeamsWebhookVerifier;
}
/**
* Target accepted by `receive(teams, { target })` for proactive sessions.
* `serviceUrl` and `conversationId` are required. Mutually exclusive:
* `replyToActivityId` threads onto an existing activity, `initialMessage` posts
* a new root that anchors non-personal threads.
*/
export interface TeamsReceiveTarget {
/** Teams team/channel id, for channel conversations. */
readonly channelId?: string;
readonly conversationId: string;
/** Teams conversation type (`personal`, `groupChat`, `channel`, or platform value). */
readonly conversationType?: string;
/** Root message posted before the session message. */
readonly initialMessage?: string | TeamsMessageBody;
/** Existing activity id to thread replies onto. */
readonly replyToActivityId?: string;
readonly serviceUrl: string;
/** Teams team id, when targeting a team channel. */
readonly teamId?: string;
/** Teams tenant id, when known. */
readonly tenantId?: string;
}
/** Result of an inbound Teams message hook. Return `null` to acknowledge without dispatching. */
export type TeamsInboundResult = {
readonly auth: SessionAuthContext | null;
readonly context?: readonly string[];
} | null;
/** Sync or async {@link TeamsInboundResult}. */
export type TeamsInboundResultOrPromise = TeamsInboundResult | Promise<TeamsInboundResult>;
/** Result of a non-HITL Teams invoke hook. A `Response` returns verbatim, a plain object is JSON-encoded as the body, and `null`/`undefined` yields a 200 OK. */
export type TeamsInvokeResult = Record<string, unknown> | Response | null | undefined;
/** Sync or async {@link TeamsInvokeResult}. */
export type TeamsInvokeResultOrPromise = TeamsInvokeResult | Promise<TeamsInvokeResult>;
type TeamsEventHandler<T extends HandleMessageStreamEvent["type"]> = (data: EventData<T>, channel: TeamsEventContext, ctx: SessionContext) => void | Promise<void>;
type TeamsSessionFailedHandler = (data: EventData<"session.failed">, channel: TeamsEventContext) => void | Promise<void>;
/** Event handlers supported by `teamsChannel({ events })`. */
export interface TeamsChannelEvents {
readonly "turn.started"?: TeamsEventHandler<"turn.started">;
readonly "actions.requested"?: TeamsEventHandler<"actions.requested">;
readonly "action.result"?: TeamsEventHandler<"action.result">;
readonly "message.completed"?: TeamsEventHandler<"message.completed">;
readonly "message.appended"?: TeamsEventHandler<"message.appended">;
readonly "input.requested"?: TeamsEventHandler<"input.requested">;
readonly "turn.failed"?: TeamsEventHandler<"turn.failed">;
readonly "turn.completed"?: TeamsEventHandler<"turn.completed">;
readonly "session.failed"?: TeamsSessionFailedHandler;
readonly "session.completed"?: TeamsEventHandler<"session.completed">;
readonly "session.waiting"?: TeamsEventHandler<"session.waiting">;
readonly "authorization.required"?: TeamsEventHandler<"authorization.required">;
readonly "authorization.completed"?: TeamsEventHandler<"authorization.completed">;
}
/** Configuration for {@link teamsChannel}. */
export interface TeamsChannelConfig {
/** Adaptive Card schema version emitted for HITL input and connection-auth cards. Defaults to `"1.5"`. */
readonly adaptiveCardVersion?: string;
/** Shared Connector API options (fetch override, login base URL). Credentials come from {@link credentials}. */
readonly api?: Omit<TeamsApiOptions, "credentials">;
/** Bot Connector credentials (app id/password, tenant id, custom token provider, or a webhook verifier). Falls back to `MICROSOFT_APP_*`/`TEAMS_APP_*` env vars when omitted. */
readonly credentials?: TeamsChannelCredentials;
/** Overrides merged over the built-in event handlers (typing, replies, HITL cards, auth cards, terminal errors). */
readonly events?: TeamsChannelEvents;
/** Inbound attachment handling. File ingestion is off unless `enabled: true`. */
readonly files?: TeamsFilesConfig;
/** Override the default webhook route path (`/eve/v1/teams`). */
readonly route?: string;
/** Inbound message hook. Defaults to user-scoped auth and mention-gated dispatch outside personal chats. */
onMessage?(ctx: TeamsContext, message: TeamsMessageActivity): TeamsInboundResultOrPromise;
/** Handler for non-HITL Teams invoke activities. Return a body, a Response, or `null`/`undefined` for a 200 OK. */
onInvoke?(ctx: TeamsContext, activity: TeamsInvokeActivity): TeamsInvokeResultOrPromise;
}
/** Low-level Teams handle exposed to hooks and event handlers. */
export interface TeamsHandle {
readonly channelId: string | undefined;
readonly conversationId: string;
readonly conversationType: string | undefined;
readonly replyToActivityId: string | undefined;
readonly serviceUrl: string;
readonly teamId: string | undefined;
readonly tenantId: string | undefined;
/** Raw Bot Connector API escape hatch. */
request(path: string, body: TeamsOutboundActivity | JsonObject, options?: TeamsRequestOptions): Promise<TeamsApiResponse>;
/** Sends a Bot Framework activity to the current conversation. */
sendActivity(activity: TeamsMessageBody | TeamsOutboundActivity | string): Promise<TeamsPostedActivity>;
/** Sends a Bot Framework reply to the current thread anchor. Throws if no anchor is set (e.g. personal chats); use {@link sendActivity} there. */
replyToActivity(activity: TeamsMessageBody | TeamsOutboundActivity | string): Promise<TeamsPostedActivity>;
updateActivity(activityId: string, activity: TeamsMessageBody | TeamsOutboundActivity | string): Promise<TeamsPostedActivity>;
/** Triggers Teams' typing indicator. The thread helper ignores failures. */
startTyping(): Promise<void>;
}
/** Conversation-scoped Teams operations. */
export interface TeamsThread {
/** Builds a Teams mention entity and matching text for one user. */
mentionUser(user: {
readonly id: string;
readonly name?: string;
}): TeamsMention;
post(message: string | TeamsMessageBody): Promise<TeamsPostedActivity>;
/** Starts Teams' typing indicator. Ignores failures. */
startTyping(): Promise<void>;
update(activityId: string, message: string | TeamsMessageBody): Promise<TeamsPostedActivity>;
}
/** Options for {@link TeamsHandle.request}. */
export interface TeamsRequestOptions {
/** HTTP verb for the raw Connector call. Defaults to `POST`. */
readonly method?: "DELETE" | "GET" | "POST" | "PUT";
}
/** Concrete return type of {@link teamsChannel}. */
export interface TeamsChannel extends Channel<TeamsChannelState, TeamsReceiveTarget, TeamsInstrumentationMetadata> {
}
/** Teams channel factory for Bot Framework Activities and proactive messages. */
export declare function teamsChannel(config?: TeamsChannelConfig): TeamsChannel;
export {};