@pouchy_ai/companion-sdk - v0.63.0
    Preparing search index...

    Interface SendTextReply

    What sendText(text, { awaitReply: true }) resolves with: the completed turn's reply. text is the authoritative final assistant text (same value onMessage receives); envelope is the full companion.message envelope for hosts that want the id/ts.

    interface SendTextReply {
        blocked?: true;
        blockedBy?: "classifier" | "term";
        blockedCategories?: string[];
        blockedWindows?: {
            categories: string[];
            end: number;
            index: number;
            start: number;
        }[];
        envelope: CompanionEnvelope;
        seq: number
        | null;
        text: string;
        usage?: TurnUsage;
    }
    Index
    blocked?: true

    The turn was refused by INBOUND MODERATION before any model ran (SDK 0.63.0): text is the configured refusal line, not something a model chose to say. Absent on every ordinary turn.

    It exists because the two were indistinguishable on the wire — same shape, same text — so an integrator could only discover a block by A/B experiment, which is exactly what issue #3379 had to do.

    blockedBy?: "classifier" | "term"

    Which gate refused: classifier is the moderation verdict (see blockedCategories), term is the operator's literal denylist. The matched term is deliberately never sent — this response reaches the app client, which may be the end user's own browser.

    blockedCategories?: string[]

    Categories that fired, on a classifier block.

    blockedWindows?: {
        categories: string[];
        end: number;
        index: number;
        start: number;
    }[]

    WHICH classifier window fired, and its char range in the scored text. blockedCategories is a union across up to six overlapping 8,000-char windows, so on a long input it says a category fired somewhere and nothing more; this localises it.

    seq: number | null
    text: string
    usage?: TurnUsage

    Turn-level token totals for cost accounting (#2955), when the server reported them: whole-turn sums plus reasoningTokens (a subset of completion) and the served model when known. Absent on turns that made no billed model call.