import { type AgentMessageStream, type AgentReplyPartDeliveryOutcome, type AgentRequestBase, type AgentResponder, type AgentResponse } from "@mono-agent/agent-contracts"; export type WebhookInvocationMode = "sync" | "async"; export interface WebhookRequestMetadata { readonly requestId: string; /** Name of the endpoint that received the request (multi-endpoint routing). */ readonly endpointName: string; readonly mode: WebhookInvocationMode; readonly method: string; readonly path: string; readonly receivedAt: string; readonly remoteAddress?: string; readonly headers: Record; readonly payloadMetadata?: unknown; /** Present when the invocation carried an audio upload (counts attachments, never bytes). */ readonly hasAttachments?: boolean; readonly attachmentCount?: number; readonly nativeNotify?: { readonly enabled: true; readonly conversationId?: string; }; /** Resolved runtime model override (request body `model` wins over endpoint config). Validated by the app. */ readonly model?: string; /** Resolved reasoning effort override (request body `effort` wins over endpoint config). Validated by the app. */ readonly effort?: string; } export interface WebhookInvocationRequest extends AgentRequestBase { readonly conversationId: string; readonly text: string; readonly abortSignal: AbortSignal; readonly metadata: { readonly webhook: WebhookRequestMetadata; readonly [key: string]: unknown; }; } export type WebhookInvocationStatus = ({ readonly status: "accepted" | "running"; readonly requestId: string; readonly conversationId: string; readonly statusUrl: string; readonly receivedAt: string; readonly startedAt?: string; } | { readonly status: "succeeded"; readonly requestId: string; readonly conversationId: string; readonly statusUrl: string; readonly receivedAt: string; readonly startedAt: string; readonly completedAt: string; readonly text?: string; readonly metadata?: Record; } | { readonly status: "failed" | "cancelled"; readonly requestId: string; readonly conversationId: string; readonly statusUrl: string; readonly receivedAt: string; readonly startedAt: string; readonly completedAt: string; readonly error: string; }) & { /** Terminal, sanitized outcomes for rich parts this adapter cannot deliver. */ readonly replyPartOutcomes?: readonly AgentReplyPartDeliveryOutcome[]; }; /** * Transport-only 409 response shape. Unlike {@link WebhookInvocationStatus}, * a busy result is never stored or replayed via the status endpoint, so it is * kept out of the persisted status union. */ export interface WebhookBusyResponse { readonly status: "busy"; readonly requestId: string; readonly conversationId: string; readonly error: string; } export interface WebhookAdapterLogger { debug?(message: string, metadata?: Record): void; info?(message: string, metadata?: Record): void; warn?(message: string, metadata?: Record): void; error?(message: string, metadata?: Record): void; } /** * Channel schemes whose request conversation may become a native-notify reply * target. WhatsApp is intentionally excluded until its plugin driver exposes a * native notify hook; explicit and host-resolved destinations remain available. */ export declare const NATIVE_NOTIFY_CALLBACK_CHANNEL_IDS: readonly ["telegram", "slack"]; /** * One HTTP endpoint of the webhook server. Multiple endpoints share one server, * host and port; each has its own POST path, default mode, optional `prompt` * (pre-instructions prepended to the incoming request text), and optional run * watchdog override. */ export interface WebhookEndpointOption { readonly name: string; readonly path: string; readonly mode?: WebhookInvocationMode; readonly prompt?: string; /** When true, the app host may deliver the final answer to a notify-capable conversation. */ readonly notify?: boolean; /** Optional destination conversationId for native notification delivery. */ readonly notifyConversationId?: string; /** * Pre-resolved fallback used after an explicit endpoint or deliverable request * conversation. Hosts with a live destination set should prefer the * adapter-level per-invocation resolver. */ readonly notifyFallbackConversationId?: string; /** Per-endpoint runtime model override (raw string; a request body `model` wins). */ readonly model?: string; /** Per-endpoint reasoning effort override (raw string; a request body `effort` wins). */ readonly effort?: string; /** * Per-endpoint wall-clock run bound in milliseconds. Wins over the adapter * fallback. Must be an integer from 0 to 86,400,000; set 0 to disable the * watchdog for this endpoint. */ readonly maxRunMs?: number; } export interface WebhookAdapterOptions { readonly host?: string; readonly port?: number; readonly allowNonLoopback?: boolean; /** Optional static bearer token. Required for every non-loopback bind. */ readonly apiKey?: string; readonly retentionMs?: number; readonly maxStoredRequests?: number; /** * Adapter-level wall-clock fallback (ms) for a webhook run. An endpoint's * `maxRunMs` wins. On timeout the request signal is aborted and the * conversation's slot is reclaimed even if the responder never settles. * Omit or set <= 0 to disable. Matters most for async runs, which have no * client disconnect to bound them. */ readonly maxRunMs?: number; /** * Decoded-byte ceiling for one inbound audio attachment (multipart/form-data * or raw `audio/*` bodies). Oversize uploads are rejected with HTTP 413. * Omit to use `DEFAULT_AGENT_ATTACHMENT_MAX_BYTES`. The 1 MB JSON limit is * unaffected. */ readonly maxAttachmentBytes?: number; readonly responder: AgentResponder; readonly logger?: WebhookAdapterLogger; /** * Host-owned fallback resolver for notify-enabled invocations without an * explicit endpoint or deliverable request destination. It runs once per * invocation so request.replyTo and completion delivery share one snapshot. * The optional signal allows cooperative cancellation; the adapter also * races resolver settlement against it. */ readonly resolveNotifyFallbackConversationId?: (abortSignal?: AbortSignal) => Promise; /** Endpoints to serve. When omitted, a single legacy endpoint is built from `path`/`defaultMode`. */ readonly endpoints?: readonly WebhookEndpointOption[]; /** Legacy single-endpoint path. Folded into a one-element `endpoints` list when `endpoints` is omitted. */ readonly path?: string; /** Default invocation mode for the legacy single endpoint and for endpoints that omit `mode`. */ readonly defaultMode?: WebhookInvocationMode; /** Best-effort completion hook; failures here must not affect HTTP responses or stored status. */ readonly onResult?: (status: WebhookInvocationStatus, request: WebhookInvocationRequest) => void | Promise; } export interface WebhookEndpointSummary { readonly name: string; readonly path: string; readonly invokeUrl: string; readonly statusBasePath: string; readonly mode: WebhookInvocationMode; } export interface WebhookAdapterStartResult { readonly url: string; /** Invoke URL of the first endpoint (back-compat). See `endpoints` for all of them. */ readonly invokeUrl: string; /** Status base path of the first endpoint (back-compat). */ readonly statusBasePath: string; readonly host: string; readonly port: number; readonly endpoints: readonly WebhookEndpointSummary[]; readonly activeRequestCount: number; getStatus(requestId: string): WebhookInvocationStatus | undefined; stop(): Promise; } export type WebhookAdapterErrorCode = "invalid_config" | "missing_required_config" | "unsafe_host" | "start_failed"; export interface WebhookAdapterErrorDetails { readonly code?: WebhookAdapterErrorCode; readonly reason?: string; readonly [key: string]: unknown; } export declare class WebhookAdapterError extends Error { readonly code: WebhookAdapterErrorCode; readonly details: WebhookAdapterErrorDetails; constructor(code: WebhookAdapterErrorCode, message: string, details?: WebhookAdapterErrorDetails); } export declare function startWebhookAdapter(options: WebhookAdapterOptions): Promise; export declare function normalizePath(path: string): string; //# sourceMappingURL=server.d.ts.map