eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
140 lines (139 loc) • 6.96 kB
TypeScript
import type { SessionAuthContext } from "#channel/types.js";
import type { HandleMessageStreamEvent } from "#protocol/message.js";
import { createLinearAgentActivity, listLinearAgentSessionActivities, updateLinearAgentSession, type LinearApiOptions } from "#public/channels/linear/api.js";
import type { LinearChannelCredentials } from "#public/channels/linear/auth.js";
import { type LinearAgentSessionEvent, type LinearAgentSessionRef, type LinearDataWebhookEvent, type LinearDelivery } from "#public/channels/linear/inbound.js";
import type { SessionContext } from "#public/definitions/callback-context.js";
import { type Channel, type ChannelSessionOps } from "#public/definitions/channel.js";
import type { JsonObject } from "#shared/json.js";
type EventData<T extends HandleMessageStreamEvent["type"]> = Extract<HandleMessageStreamEvent, {
type: T;
}> extends {
data: infer D;
} ? D : undefined;
/** JSON-serializable state for one Linear Agent Session conversation. */
export interface LinearChannelState {
readonly agentSessionId: string | null;
readonly agentSessionUrl?: string | null;
readonly commentId?: string | null;
readonly issueId?: string | null;
readonly issueIdentifier?: string | null;
readonly issueTitle?: string | null;
readonly issueUrl?: string | null;
readonly organizationId?: string | null;
/**
* Buffered text from a `message.completed` event whose `finishReason`
* was `"tool-calls"`. The default `actions.requested` handler uses this
* as the next ephemeral progress activity, matching Slack's typing status.
*/
pendingToolCallMessage?: string | null;
readonly sourceCommentId?: string | null;
}
/** Per-session instrumentation snapshot for Linear runtime telemetry. */
export interface LinearInstrumentationMetadata extends Record<string, unknown> {
readonly agentSessionId: string | null;
readonly commentId: string | null;
readonly issueId: string | null;
readonly issueIdentifier: string | null;
readonly organizationId: string | null;
}
/** Target accepted by `receive(linear, { target })` for proactive Linear sessions. */
export type LinearReceiveTarget = {
readonly agentSessionId: string;
readonly initialActivity?: string;
} | {
readonly externalLink?: string;
readonly externalUrls?: readonly {
readonly label: string;
readonly url: string;
}[];
readonly initialActivity?: string;
readonly issueId: string;
} | {
readonly commentId: string;
readonly externalLink?: string;
readonly externalUrls?: readonly {
readonly label: string;
readonly url: string;
}[];
readonly initialActivity?: string;
};
/** Pre-dispatch Linear context passed to inbound hooks. */
export interface LinearSessionContext {
readonly delivery: LinearDelivery;
readonly linear: LinearHandle;
readonly session: LinearAgentSessionRef;
}
/** Channel-owned Linear context rebuilt from persisted channel state. */
export interface LinearChannelContext {
readonly linear: LinearHandle;
state: LinearChannelState;
}
/** Event-handler Linear context, including session operations. */
export interface LinearEventContext extends LinearChannelContext, ChannelSessionOps {
}
/** Low-level Linear handle exposed to hooks and event handlers. */
export interface LinearHandle {
readonly agentSessionId: string;
createActivity(content: Parameters<typeof createLinearAgentActivity>[0]["activity"]["content"], options?: {
readonly ephemeral?: boolean;
readonly signal?: Parameters<typeof createLinearAgentActivity>[0]["activity"]["signal"];
readonly signalMetadata?: JsonObject;
}): Promise<{
readonly id: string;
readonly success: boolean;
}>;
listActivities(options?: {
readonly last?: number;
}): Promise<Awaited<ReturnType<typeof listLinearAgentSessionActivities>>>;
updateSession(update: Parameters<typeof updateLinearAgentSession>[0]["update"]): Promise<{
readonly success: boolean;
}>;
}
type LinearEventHandler<T extends HandleMessageStreamEvent["type"]> = (data: EventData<T>, channel: LinearEventContext, ctx: SessionContext) => void | Promise<void>;
type LinearSessionFailedHandler = (data: EventData<"session.failed">, channel: LinearEventContext) => void | Promise<void>;
/** Event handlers supported by `linearChannel({ events })`. */
export interface LinearChannelEvents {
readonly "turn.started"?: LinearEventHandler<"turn.started">;
readonly "actions.requested"?: LinearEventHandler<"actions.requested">;
readonly "action.result"?: LinearEventHandler<"action.result">;
readonly "message.completed"?: LinearEventHandler<"message.completed">;
readonly "message.appended"?: LinearEventHandler<"message.appended">;
readonly "input.requested"?: LinearEventHandler<"input.requested">;
readonly "turn.failed"?: LinearEventHandler<"turn.failed">;
readonly "turn.completed"?: LinearEventHandler<"turn.completed">;
readonly "turn.cancelled"?: LinearEventHandler<"turn.cancelled">;
readonly "session.failed"?: LinearSessionFailedHandler;
readonly "session.completed"?: LinearEventHandler<"session.completed">;
readonly "session.waiting"?: LinearEventHandler<"session.waiting">;
readonly "authorization.required"?: LinearEventHandler<"authorization.required">;
readonly "authorization.completed"?: LinearEventHandler<"authorization.completed">;
}
/**
* Result of an inbound Linear hook. Return `null` to acknowledge without
* dispatching; return `{ auth }` to dispatch. Optional `context` strings are
* added as `role: "user"` messages before the dispatched turn.
*/
export type LinearInboundResult = {
readonly auth: SessionAuthContext | null;
readonly context?: readonly string[];
} | null;
/** Sync or async {@link LinearInboundResult}. */
export type LinearInboundResultOrPromise = LinearInboundResult | Promise<LinearInboundResult>;
/** Configuration for {@link linearChannel}. */
export interface LinearChannelConfig {
readonly api?: LinearApiOptions;
readonly credentials?: LinearChannelCredentials;
readonly events?: LinearChannelEvents;
readonly route?: string;
/** Inbound Agent Session hook. Defaults to dispatching `created` and `prompted` events. */
onAgentSession?(ctx: LinearSessionContext, event: LinearAgentSessionEvent): LinearInboundResultOrPromise;
/** Optional hook for generic Linear data webhooks sent to the same route. */
onDataWebhook?(event: LinearDataWebhookEvent): void | Promise<void>;
}
/** Concrete return type of {@link linearChannel}. */
export interface LinearChannel extends Channel<LinearChannelState, LinearReceiveTarget, LinearInstrumentationMetadata> {
}
/** Linear channel factory for Linear Agent Session webhooks and Agent Activities. */
export declare function linearChannel(config?: LinearChannelConfig): LinearChannel;
export {};