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

    Interface CompanionView

    interface CompanionView {
        client: CompanionClient;
        sendText: {
            (
                text: string,
                opts: {
                    awaitReply: true;
                    images?: string[];
                    instructions?: string;
                    replyTimeoutMs?: number;
                    signal?: AbortSignal;
                    stream?: boolean;
                    turnId?: string;
                },
            ): Promise<SendTextReply>;
            (
                text: string,
                opts?: {
                    awaitReply?: boolean;
                    images?: string[];
                    instructions?: string;
                    replyTimeoutMs?: number;
                    signal?: AbortSignal;
                    stream?: boolean;
                    turnId?: string;
                },
            ): Promise<
                {
                    duplicate?: true;
                    queued?: boolean;
                    seq: number
                    | null;
                    turnId?: string;
                },
            >;
        };
        confirmAction(
            confirmId: string,
            approve: boolean,
            opts?: { signal?: AbortSignal },
        ): Promise<ConfirmActionResult>;
        dispose(): void;
        getSnapshot(): CompanionViewSnapshot;
        subscribe(listener: () => void): () => void;
    }
    Index

    The underlying client, for everything the view doesn't wrap.

    sendText: {
        (
            text: string,
            opts: {
                awaitReply: true;
                images?: string[];
                instructions?: string;
                replyTimeoutMs?: number;
                signal?: AbortSignal;
                stream?: boolean;
                turnId?: string;
            },
        ): Promise<SendTextReply>;
        (
            text: string,
            opts?: {
                awaitReply?: boolean;
                images?: string[];
                instructions?: string;
                replyTimeoutMs?: number;
                signal?: AbortSignal;
                stream?: boolean;
                turnId?: string;
            },
        ): Promise<
            {
                duplicate?: true;
                queued?: boolean;
                seq: number
                | null;
                turnId?: string;
            },
        >;
    }

    sendText that also appends the user turn to the transcript. Typed as the client's own overloaded signature (CR-1054): Parameters / ReturnType see only the LAST overload, so an awaitReply: true send was typed as the plain ack and its reply text did not type-check.

    Type Declaration

      • (
            text: string,
            opts: {
                awaitReply: true;
                images?: string[];
                instructions?: string;
                replyTimeoutMs?: number;
                signal?: AbortSignal;
                stream?: boolean;
                turnId?: string;
            },
        ): Promise<SendTextReply>
      • Send a user text turn, optionally with images (data URLs) for a multimodal turn — images need the files scope. The reply arrives on the event stream as a companion.message — subscribe via onMessage()/start() to receive it.

        TOKEN STREAMING (P1-2): when any onDelta() subscriber is registered (or opts.stream is true), the reply streams token-by-token on this very request — delta subscribers fire as chunks arrive, and onMessage still fires exactly ONCE with the authoritative final text (the streamed copy is emitted locally; the event-stream replay of the same envelope is deduplicated by id). Pass stream: false to force the buffered path.

        AWAIT THE REPLY (request/response hosts — a REPL, an HTTP handler, a test): pass awaitReply: true and the promise resolves with the final reply { seq, text, envelope } — no onMessage wiring, no hand-rolled turn gate. It rides the same streaming request (the terminal done frame carries the authoritative envelope), so it works without start(); onMessage/onDelta subscribers still fire as usual. Only when the reply can't ride the request (stream: false, or an old server) does it fall back to the event stream — which then DOES need start() — resolving with the next companion.message, or rejecting with code reply_timeout after replyTimeoutMs (default 60s).

        OFFLINE QUEUE (0.34.0, opt-in queueOffline: true): a send that never REACHED the server — fetch rejected at the network level, or navigator.onLine is already false — is queued for replay instead of lost, and resolves { seq: null, queued: true, turnId }. With awaitReply: true there is no reply to await this session, so it rejects with code queued_offline (the item IS queued first). HTTP error responses keep the throw semantics above — they are never queued.

        RETRY (0.72.0): every result carries the turnId it went out under; pass it back as opts.turnId after an ambiguous failure and the server replays the completed turn (duplicate: true, no model call, no bill) instead of running a second one. 1–256 chars (64 before 0.73.2), else invalid_option.

        Parameters

        • text: string
        • opts: {
              awaitReply: true;
              images?: string[];
              instructions?: string;
              replyTimeoutMs?: number;
              signal?: AbortSignal;
              stream?: boolean;
              turnId?: string;
          }

        Returns Promise<SendTextReply>

      • (
            text: string,
            opts?: {
                awaitReply?: boolean;
                images?: string[];
                instructions?: string;
                replyTimeoutMs?: number;
                signal?: AbortSignal;
                stream?: boolean;
                turnId?: string;
            },
        ): Promise<
            {
                duplicate?: true;
                queued?: boolean;
                seq: number
                | null;
                turnId?: string;
            },
        >
      • Send a user text turn, optionally with images (data URLs) for a multimodal turn — images need the files scope. The reply arrives on the event stream as a companion.message — subscribe via onMessage()/start() to receive it.

        TOKEN STREAMING (P1-2): when any onDelta() subscriber is registered (or opts.stream is true), the reply streams token-by-token on this very request — delta subscribers fire as chunks arrive, and onMessage still fires exactly ONCE with the authoritative final text (the streamed copy is emitted locally; the event-stream replay of the same envelope is deduplicated by id). Pass stream: false to force the buffered path.

        AWAIT THE REPLY (request/response hosts — a REPL, an HTTP handler, a test): pass awaitReply: true and the promise resolves with the final reply { seq, text, envelope } — no onMessage wiring, no hand-rolled turn gate. It rides the same streaming request (the terminal done frame carries the authoritative envelope), so it works without start(); onMessage/onDelta subscribers still fire as usual. Only when the reply can't ride the request (stream: false, or an old server) does it fall back to the event stream — which then DOES need start() — resolving with the next companion.message, or rejecting with code reply_timeout after replyTimeoutMs (default 60s).

        OFFLINE QUEUE (0.34.0, opt-in queueOffline: true): a send that never REACHED the server — fetch rejected at the network level, or navigator.onLine is already false — is queued for replay instead of lost, and resolves { seq: null, queued: true, turnId }. With awaitReply: true there is no reply to await this session, so it rejects with code queued_offline (the item IS queued first). HTTP error responses keep the throw semantics above — they are never queued.

        RETRY (0.72.0): every result carries the turnId it went out under; pass it back as opts.turnId after an ambiguous failure and the server replays the completed turn (duplicate: true, no model call, no bill) instead of running a second one. 1–256 chars (64 before 0.73.2), else invalid_option.

        Parameters

        • text: string
        • Optionalopts: {
              awaitReply?: boolean;
              images?: string[];
              instructions?: string;
              replyTimeoutMs?: number;
              signal?: AbortSignal;
              stream?: boolean;
              turnId?: string;
          }

        Returns Promise<
            {
                duplicate?: true;
                queued?: boolean;
                seq: number
                | null;
                turnId?: string;
            },
        >

    • confirmAction that also removes the confirm from pendingConfirms (on approve AND deny — both resolve the card server-side).

      Parameters

      • confirmId: string
      • approve: boolean
      • Optionalopts: { signal?: AbortSignal }

      Returns Promise<ConfirmActionResult>

    • Detach every client subscription. The view goes inert (snapshot frozen, listeners dropped); the client itself is NOT closed — it belongs to the host. Idempotent.

      Returns void

    • Subscribe to snapshot changes. Returns unsubscribe.

      Parameters

      • listener: () => void

      Returns () => void