/** * ShuttleAdapter — the base every channel builds on (SH1 + SH2). * * It owns the steps a messaging channel shares, so a channel (Telegram, Slack, * SMS…) only normalizes its platform's updates into a {@link ShuttleMessage} * and provides a {@link ChannelTransport}: * * 1. RECEIVE the channel hands us a normalized ShuttleMessage * 2. GATE decide WHETHER/HOW to answer → a reply disposition (SH2) * 3. DRIVE key it (session-key oracle) → resolve the thread → POST /run * 4. DELIVER tail the reply and send it back to the SOURCE (deterministic — * the model never picks the channel), per the delivery mode */ import { type LinePolicy, type ResponseGate, type LlmGate } from './gate.js'; import type { ChannelTransport, DeliveryPolicy, DeliveryResult } from './delivery.js'; import type { ShuttleMessage, GroupPolicy, ThreadMap } from './types.js'; import type { PairingStore } from './pairing.js'; import type { GatewayClient } from './gateway-client.js'; export interface ShuttleConfig { /** Which agent answers (profile slug). */ readonly profileId: string; /** Which channel this shuttle is (e.g. `telegram`). */ readonly channel: string; /** How the reply is delivered on this platform. */ readonly delivery: DeliveryPolicy; /** The access + response policy (personal ↔ business). */ readonly line?: LinePolicy; /** Back-compat shortcut for `line.group`. */ readonly groupPolicy?: GroupPolicy; /** Isolate each group participant into their own thread. Default false. */ readonly groupPerUser?: boolean; /** Coalesce rapid messages per person before answering (SH-deb). Off if omitted. */ readonly debounce?: { readonly ms: number; readonly maxWaitMs?: number; }; /** * How long a pause-for-approval stays answerable from this chat * (ms). Mirrors the gateway's HITL window — after it, the gateway * has already denied the request, so the stale entry is dropped. * Default 30 minutes. */ readonly approvalTtlMs?: number; } export interface ShuttleDeps { readonly gateway: GatewayClient; readonly threads: ThreadMap; readonly transport: ChannelTransport; /** Override the default policy gate entirely. */ readonly gate?: ResponseGate; /** Pairing store (required when `line.dm: 'pairing'`). */ readonly pairing?: PairingStore; /** Optional cheap LLM "is this for us?" pre-filter. */ readonly llmGate?: LlmGate; /** Whether a thread is handed off to a human right now. */ readonly isPaused?: (msg: ShuttleMessage) => boolean | Promise; } export declare class ShuttleAdapter { private readonly config; private readonly deps; private readonly cursors; private readonly gate; private readonly debouncer; /** * Pause-for-approval state, per session key. A FIFO queue: the * loop asks serially for write tools, but parallel read-only calls * can raise several approvals at once — a reply answers the OLDEST, * then the next one is re-prompted. */ private readonly pendingApprovals; constructor(config: ShuttleConfig, deps: ShuttleDeps); /** The canonical session key for a message (one thread per person). */ keyFor(msg: ShuttleMessage): string; /** * Handle one inbound message. With debounce configured, rapid messages from * the same person are buffered and answered once (this returns `null` and the * reply is delivered when the batch flushes). Otherwise it processes inline * and returns what was delivered (or `null` if the gate dropped it). */ handle(msg: ShuttleMessage): Promise; /** * While a run is paused on an approval for this chat, EVERY inbound * message is the decision surface: yes/no answers it; anything else * gets a one-line hint (the paused thread couldn't take a new prompt * anyway — the gateway 409s an active thread). Returns true when the * message was consumed here. */ private interceptApprovalReply; /** Gate → act on the disposition. The core per-message decision. */ private process; /** Flush handler: combine a person's buffered messages into one and process. */ private processBatch; /** The agent path: key → resolve/reuse thread → run → tail → deliver back. */ private runAndDeliver; } export type { ShuttleMessage, GroupPolicy } from './types.js'; export type { ChannelTransport, DeliveryPolicy, DeliveryResult }; //# sourceMappingURL=adapter.d.ts.map