import { type WebchatChannelRole } from './instructions.js'; /** Task 1516 — the dispatcher's operator-provenance marker, present only on a * scheduled inject. A local copy of the shape (this package never cross-imports * platform/ui). Kept byte-identical to the whatsapp/telegram twins. */ export interface ScheduleProvenance { accountId: string; eventId: string; authoredBy: string[]; createdByTool: string | null; dispatchedAt: string; } /** * Task 1516 — render the dispatcher's operator-provenance as a platform-verified * preamble. Every value is dispatcher-stamped (an inbound message cannot produce * this block), so the grounding treats a turn opening with it as an authorised * standing automation. Copy stays operator-clean (no task numbers, repo paths, or * em-dashes). Byte-identical to the whatsapp/telegram twins. */ export declare function composeScheduleMarker(pv: ScheduleProvenance): string; export interface InboundPayload { /** The webchat conversation key this payload is for. */ key: string; /** The operator's typed message, verbatim — multi-line content is preserved. */ text: string; /** Per-message id, for dedup/observability. */ messageId: string; /** Task 1486 — the account's active standing-rules block (already formatted as * `## Standing rules`), fetched and attached by the gateway. Prepended above * `## Context` for ADMIN turns only; a public visitor never receives it. * Absent/blank when the account has no active rules. */ standingRules?: string; /** Task 1516 — the dispatcher's operator-provenance marker on a scheduled * inject; rendered above `## Context` (and above the rules block) for ADMIN * turns only. Absent on a real inbound. */ scheduleProvenance?: ScheduleProvenance; } /** The composed content the agent receives, plus the inner payload's byte * length for the observability line. */ export interface ComposedInbound { content: string; payloadBytes: number; } /** Frame an ADMIN inbound as `## Context` (the typed message) then * `## Instruction` (the routing + capability-denial directive), so the * directive rides every turn. PUBLIC stays plain: the public reader echoes the * visitor's own inbound back to them, so wrapping it would leak the internal * directive to the visitor (Task 899). `payloadBytes` is the inner message * length, excluding any wrapper — matching the WhatsApp `[reframe]` semantics. */ export declare function composeContent(p: InboundPayload, role: WebchatChannelRole): ComposedInbound; /** Defence in depth: this server serves exactly one key. Even though the * gateway only streams that key's messages, refuse anything else before it * reaches the session. */ export declare function acceptsKey(myKey: string, p: { key: string; }): boolean; /** Build the body for POST /webchat-channel/reply. The reply tool exposes only * `text` to the model; the key is the server's fixed key (from spawn env), * never trusted from the model, so a compromised turn cannot redirect a reply * to a different conversation. */ export declare function buildReplyPostBody(myKey: string, text: string): { key: string; text: string; }; /** Build the body for POST /webchat-channel/received — the receipt ack the * channel server sends after it has emitted a drained inbound to the agent, * so the gateway marks it delivered instead of sweeping it as * drain-undelivered. The key is the server's fixed key, never model-supplied. */ export declare function buildReceivedPostBody(myKey: string, messageId: string): { key: string; messageId: string; }; /** * Build the body for POST /webchat-channel/turn-end — the turn-end decision the * channel server posts once per turn (Task 980 / 1539). `key` + `sessionId` are * the server's fixed values (spawn env), never model-supplied. `replied` is * whether a webchat reply tool_use occurred in the turn; `interactive` is true * when a real person is waiting (webchat has no scheduler dispatch, so this is * always true today — `!scheduleProvenance`); `finalBytes` is the byte length of * the trimmed end_turn assistant text. Divergence from the WhatsApp/Telegram * twins: the raw answer text is NOT sent. Webchat delivery is reader-side — the * admin transcript promotes the end-turn text to a delivered bubble (Task 1539) — * so the gateway needs only `interactive` + `finalBytes` to classify the outcome * for the lifeline, never the answer text. */ export declare function buildTurnEndPostBody(myKey: string, sessionId: string, replied: boolean, interactive: boolean, finalBytes: number): { key: string; sessionId: string; replied: boolean; interactive: boolean; finalBytes: number; }; /** Retry an idempotent POST until it is accepted or the attempt cap is * reached. `attempt` returns whether the POST was accepted; the helper * returns on the first acceptance, otherwise sleeps `delayMs` and retries, * up to `attempts` total. `sleep` is injected so tests run without real * timers. */ export declare function postWithRetry(attempt: () => Promise, opts: { attempts: number; delayMs: number; sleep: (ms: number) => Promise; }): Promise; /** Map a non-OK /webchat-channel/reply response into an actionable MCP error * string. Falls back to the bare status when the body carries no usable * reason. (No terminal/logged-out branch — there is no external transport to * log out of.) */ export declare function buildReplyError(status: number, body: unknown): string; export declare const INTERNAL_LEAK_PATTERNS: { name: string; re: RegExp; }[]; export interface Redaction { pattern: string; match: string; } export declare function redactInternalLeaks(text: string): { clean: string; redactions: Redaction[]; }; //# sourceMappingURL=notification.d.ts.map