Interface MeetingManagerConfig

How a host builds a MeetingManager: its stores, its room helper, its routes and its limits.

interface MeetingManagerConfig {
    managerId?: string;
    stores: MeetingManagerStores;
    room: MeetingRoom;
    reportUrlFor: ((runId, providerName) => string);
    destinationsFor?: ((ownerRef) => Promise<string[]>);
    purgeHooks?: ((runId) => Promise<void>)[];
    scrubUnkeptOutbox?: boolean;
    beforeComplete?: ((run, turns) => Promise<void>);
    leaseTtlMs?: number;
    noticeConfirmMs?: number;
    monitorHeartbeatMs?: number;
    monitorMissedBeats?: number;
    monitorRecoverMs?: number;
    dispatchRetryMs?: number;
    dispatchRetryDelayMs?: number;
    killAfterMs?: number;
    usageSilenceMs?: number;
    forgetAfterMs?: number;
    minReservationSeconds?: number;
    creation?: {
        withOwnerLock: (<T>(ownerRef, work) => Promise<T>);
        admit?: ((request, context) => Promise<void>);
        prepare: ((run, context) => Promise<void>);
        funding?: ((request, context, runId) => Promise<{
            accountRef: string;
            policyVersion: string;
            reservationRef: string;
            maxSeconds: number;
            expiresAt: number;
            fundingMode: "bot_blocks";
            blockSeconds: number;
            maxLiability: {
                blocks: number;
            };
        } | {
            accountRef: string;
            policyVersion: string;
            reservationRef: string;
            maxSeconds: number;
            expiresAt: number;
            fundingMode: "developer_credit";
            rates: {
                version: string;
                currency: "USD";
                reasoningInOutput: boolean;
                components: Record<string, {
                    customer: {
                        unit: ...;
                        micro: ...;
                        per: ...;
                    };
                    supplier: {
                        unit: ...;
                        micro: ...;
                        per: ...;
                    };
                }>;
                attemptMinimum?: {
                    customerMicro: number;
                    supplierMicro: number;
                };
            };
            mediaComponent: string;
            maxLiability: {
                customerMicro: number;
                supplierMicro: number;
            };
        }>);
    };
    dispatchGuard?: ((run, work) => Promise<void>);
    logger?: {
        info(msg): void;
        warn(msg): void;
        error(msg): void;
    };
}

Properties

managerId?: string

This process, as the holder of dispatch leases.

Where every run's rows, jobs, turns, events and deliveries are kept.

Makes each run's room at dispatch and deletes it at the end.

reportUrlFor: ((runId, providerName) => string)

The product's events route for a provider's reports about a run.

Type declaration

    • (runId, providerName): string
    • Parameters

      • runId: string
      • providerName: string

      Returns string

destinationsFor?: ((ownerRef) => Promise<string[]>)

The product's destinations (webhook registrations) for an owner; absent, nothing is enqueued.

Type declaration

    • (ownerRef): Promise<string[]>
    • Parameters

      • ownerRef: string

      Returns Promise<string[]>

purgeHooks?: ((runId) => Promise<void>)[]

The product's steps of the purge sequence: the agent's history, the kept session, the page. Each is retried until it resolves.

Type declaration

    • (runId): Promise<void>
    • Parameters

      • runId: string

      Returns Promise<void>

scrubUnkeptOutbox?: boolean

Whether the completion of a run kept nowhere (keep: 'none') empties the run's content deliveries in the outbox, pending and delivered ones, before the run is done, as a purge does: an outbox with sendClaimed also cancels the run's send under way, and a FencedOutbox stores every later delivery of the run without content. Default true. False leaves the run's deliveries to their retries, so a destination still receives the content deliveries pending at completion. The run's transcript and event payloads are removed either way, and a purge of the run empties its deliveries whatever this says.

beforeComplete?: ((run, turns) => Promise<void>)

Optional. The host's step before a run's settle and scrub, awaited with the run as it stands in left and every turn the run stored, once the transcript is fenced (no turn can arrive after it). A step that throws is logged by its error's name, and the completion goes on: the run ends done and a run not kept loses its content all the same. It is not run for a run the stop phrase or a purge ended, nor for a failed run (neither has turns to give). It runs once per run: the cleanup claims the run before the step (completionHookClaimedAt), so a tick's cleanup that overlaps a report's, or another instance's, waits for it rather than running it again, and the scrub of a run not kept comes after the step whichever cleanup finishes; a claim a stopped process left is taken over once it is COMPLETION_HOOK_LEASE_MS old.

Type declaration

leaseTtlMs?: number

How long a dispatch lease lasts; renewed every third of it while a dispatch is in flight. Default 60000.

noticeConfirmMs?: number

How long after in_call the notice may go unconfirmed before the run leaves with notice_failed. Default 30000.

monitorHeartbeatMs?: number

How often the stop monitor reports. Default 10000.

monitorMissedBeats?: number

How many heartbeats the stop monitor may miss before it counts as unhealthy: it does once this many heartbeat intervals pass without one (30 seconds with the defaults). Default 3.

monitorRecoverMs?: number

How long a suspended capture waits for the stop monitor to recover before the run leaves with stop_monitor_failed. Default 30000.

dispatchRetryMs?: number

How long after its due time a dispatch keeps being retried before the run fails. Default 300000.

dispatchRetryDelayMs?: number

The pause before a failed dispatch is tried again. Default 15000.

killAfterMs?: number

How long after a leave command the bot is killed. Default 30000.

usageSilenceMs?: number

End at the last durable usage after this silence. Omitted preserves the existing reconciliation policy. When set, a dispatching or dispatched run whose worker has sent no fresh usage report for this many milliseconds (counted from the manager's receipt of the last one, or from the dispatch when none came) is killed and ended crashed, at that receipt and at the total the reports gave, whatever the provider answers and whatever heartbeats arrive. Every pass of the upkeep checks it, and so does MeetingManager.reconcile. A value that is not a finite number of milliseconds above zero is refused with a RangeError when the manager is built, and so, with a TypeError, is a run store without updateWith (IRunStore.updateWith): the usage reports and the silence's ends are decided on the stored row in the write, which a read followed by an update cannot do.

forgetAfterMs?: number

In-memory terminal records live for this grace; default two days, beyond the outbox retry window.

minReservationSeconds?: number

The least a reservation may cover for a run to be sent, in seconds; a send under it is refused with allowance. Default 600.

creation?: {
    withOwnerLock: (<T>(ownerRef, work) => Promise<T>);
    admit?: ((request, context) => Promise<void>);
    prepare: ((run, context) => Promise<void>);
    funding?: ((request, context, runId) => Promise<{
        accountRef: string;
        policyVersion: string;
        reservationRef: string;
        maxSeconds: number;
        expiresAt: number;
        fundingMode: "bot_blocks";
        blockSeconds: number;
        maxLiability: {
            blocks: number;
        };
    } | {
        accountRef: string;
        policyVersion: string;
        reservationRef: string;
        maxSeconds: number;
        expiresAt: number;
        fundingMode: "developer_credit";
        rates: {
            version: string;
            currency: "USD";
            reasoningInOutput: boolean;
            components: Record<string, {
                customer: {
                    unit: ...;
                    micro: ...;
                    per: ...;
                };
                supplier: {
                    unit: ...;
                    micro: ...;
                    per: ...;
                };
            }>;
            attemptMinimum?: {
                customerMicro: number;
                supplierMicro: number;
            };
        };
        mediaComponent: string;
        maxLiability: {
            customerMicro: number;
            supplierMicro: number;
        };
    }>);
}

Optional: the host's part in MeetingManager.sendBotPrepared, which requires it. Absent, a run is sent with MeetingManager.sendBot alone.

Type declaration

  • withOwnerLock: (<T>(ownerRef, work) => Promise<T>)

    Runs work while the host holds its lock for the owner: the lock its other sends, and its dispatchGuard, take.

      • <T>(ownerRef, work): Promise<T>
      • Type Parameters

        • T

        Parameters

        • ownerRef: string
        • work: (() => Promise<T>)
            • (): Promise<T>
            • Returns Promise<T>

        Returns Promise<T>

  • Optional admit?: ((request, context) => Promise<void>)

    The host's admission of a new send, under that lock, before any run is written; it throws to refuse the send. A send its idempotency key repeats is not asked again.

      • (request, context): Promise<void>
      • Parameters

        Returns Promise<void>

  • prepare: ((run, context) => Promise<void>)

    The host's preparation, committed before the run's job exists: called with the run once its reservation is written, and again, with the same run and context, when an interruption cut the creation short; so it is idempotent.

      • (run, context): Promise<void>
      • Parameters

        Returns Promise<void>

  • Optional funding?: ((request, context, runId) => Promise<{
        accountRef: string;
        policyVersion: string;
        reservationRef: string;
        maxSeconds: number;
        expiresAt: number;
        fundingMode: "bot_blocks";
        blockSeconds: number;
        maxLiability: {
            blocks: number;
        };
    } | {
        accountRef: string;
        policyVersion: string;
        reservationRef: string;
        maxSeconds: number;
        expiresAt: number;
        fundingMode: "developer_credit";
        rates: {
            version: string;
            currency: "USD";
            reasoningInOutput: boolean;
            components: Record<string, {
                customer: {
                    unit: ...;
                    micro: ...;
                    per: ...;
                };
                supplier: {
                    unit: ...;
                    micro: ...;
                    per: ...;
                };
            }>;
            attemptMinimum?: {
                customerMicro: number;
                supplierMicro: number;
            };
        };
        mediaComponent: string;
        maxLiability: {
            customerMicro: number;
            supplierMicro: number;
        };
    }>)

    Server-selected once before insertion; requires prepared creation and a dispatch guard. The host's choice of a new send's funding, under the owner's lock, after admit, with the id the run is written under: the snapshot it answers is written with the run (MeetingRunRecord.funding) and decides the run's funding from then on, and a send its idempotency key repeats answers the stored run without asking again. A manager given it refuses sendBot, and sendBotPrepared throws unless the manager has a dispatchGuard, the entitlement hook has checkRun, recover and finalize, and the run store has listFundingPending.

      • (request, context, runId): Promise<{
            accountRef: string;
            policyVersion: string;
            reservationRef: string;
            maxSeconds: number;
            expiresAt: number;
            fundingMode: "bot_blocks";
            blockSeconds: number;
            maxLiability: {
                blocks: number;
            };
        } | {
            accountRef: string;
            policyVersion: string;
            reservationRef: string;
            maxSeconds: number;
            expiresAt: number;
            fundingMode: "developer_credit";
            rates: {
                version: string;
                currency: "USD";
                reasoningInOutput: boolean;
                components: Record<string, {
                    customer: {
                        unit: ...;
                        micro: ...;
                        per: ...;
                    };
                    supplier: {
                        unit: ...;
                        micro: ...;
                        per: ...;
                    };
                }>;
                attemptMinimum?: {
                    customerMicro: number;
                    supplierMicro: number;
                };
            };
            mediaComponent: string;
            maxLiability: {
                customerMicro: number;
                supplierMicro: number;
            };
        }>
      • Parameters

        Returns Promise<{
            accountRef: string;
            policyVersion: string;
            reservationRef: string;
            maxSeconds: number;
            expiresAt: number;
            fundingMode: "bot_blocks";
            blockSeconds: number;
            maxLiability: {
                blocks: number;
            };
        } | {
            accountRef: string;
            policyVersion: string;
            reservationRef: string;
            maxSeconds: number;
            expiresAt: number;
            fundingMode: "developer_credit";
            rates: {
                version: string;
                currency: "USD";
                reasoningInOutput: boolean;
                components: Record<string, {
                    customer: {
                        unit: ...;
                        micro: ...;
                        per: ...;
                    };
                    supplier: {
                        unit: ...;
                        micro: ...;
                        per: ...;
                    };
                }>;
                attemptMinimum?: {
                    customerMicro: number;
                    supplierMicro: number;
                };
            };
            mediaComponent: string;
            maxLiability: {
                customerMicro: number;
                supplierMicro: number;
            };
        }>

dispatchGuard?: ((run, work) => Promise<void>)

Host serializes dispatch admission with its other sends. It invokes work only when admitted. The manager calls it for each leased job of a run that waits for its dispatch, or whose dispatch is recovered, with the run as leased; work reads the run again and dispatches it. A dispatch it does not admit keeps its lease and is offered again once the lease runs out (leaseTtlMs), or sooner when the host releases the job (IJobStore.release, under the manager's managerId).

Type declaration

    • (run, work): Promise<void>
    • Parameters

      • run: MeetingRunRecord
      • work: (() => Promise<void>)
          • (): Promise<void>
          • Returns Promise<void>

      Returns Promise<void>

logger?: {
    info(msg): void;
    warn(msg): void;
    error(msg): void;
}

Where the manager writes its warnings and errors.

Type declaration