import type { AIProviderType, TurnFailureReason } from '@genesislcap/foundation-ai';
/**
 * Event map for the AI activity bus.
 *
 * Declare-merge this interface to add your own event types:
 * ```ts
 * declare module '@genesislcap/ai-assistant' {
 *   interface AgenticActivityEvents {
 *     'grid-flash-rows': { gridId: string; rowIds: string[] };
 *   }
 * }
 * ```
 *
 * @beta
 */
export interface AgenticActivityEvents {
    /** Fired when the assistant begins a tool call. Contains the names of all active tools. */
    'halo-start': {
        toolNames: string[];
    };
    /** Fired when the assistant finishes all tool processing and returns to idle. */
    'halo-stop': undefined;
    /** Fired when the user clicks the expand button — moves assistant from bubble into layout. State lives in the session store, not in this event. */
    'chat-popout': undefined;
    /** Fired when the user clicks the collapse button — moves assistant from layout back to bubble. State lives in the session store, not in this event. */
    'chat-popin': undefined;
    /**
     * Fired immediately before the tool loop begins running for the current turn — after the busy
     * flag is set and the user message (if any) has been appended, but before the first
     * provider call. Pairs with {@link AgenticActivityEvents.'tool-loop-end'}.
     *
     * Boundary: this is the moment the assistant takes control from the user on the **main chat
     * prompt** to begin a turn. It is **not** fired when a tool handler temporarily hands a
     * widget to the user mid-loop (e.g. `requestInteraction` pausing a handler while a planning
     * widget is rendered) — those widget pauses happen inside the loop and the assistant is
     * still considered to own the turn.
     *
     * Fires from each `ChatDriver`'s `sendMessage` and `continueFromHistory`, so during a
     * multi-agent handoff orchestrated by `OrchestratingDriver` it fires once per agent
     * the orchestrator hands off to.
     *
     * Distinct from {@link AgenticActivityEvents.'halo-start'} — the halo event is keyed to
     * tool-call messages arriving in the stream (UI animation concern), not to the loop boundary
     * itself. Use this event for hooks tied to a turn beginning (telemetry, transient UI gates).
     */
    'tool-loop-start': undefined;
    /**
     * Fired when the tool loop completes for the current turn and control returns to the user
     * on the **main chat prompt** (i.e. the next free-form user message can now be accepted).
     *
     * Boundary: this is the moment the user regains control of the main chat input. It is
     * **not** fired when a tool handler hands a widget to the user mid-loop (e.g. while a
     * planning widget is awaiting a click) — widget pauses are still inside the loop, the
     * assistant still owns the turn, and the main chat input may be hidden during them. Wait
     * for this event when you need to know that the assistant is fully idle and the user can
     * type freely again.
     *
     * Emitted from the finally block of each `ChatDriver`'s `sendMessage` and
     * `continueFromHistory`, so a multi-agent handoff fires this event once per agent.
     *
     * Distinct from {@link AgenticActivityEvents.'halo-stop'} — the halo event tracks the
     * spinner animation lifecycle (which can flap mid-turn as tool calls resolve), whereas
     * this event is a one-shot per turn boundary. Use this for hooks tied to a turn ending
     * (telemetry flushes, post-turn workspace transitions, deferred state recomputation).
     *
     * The detail carries the turn's outcome (PTC-0): on a failure it is `{ failureReason }`
     * with the typed `TurnFailureReason`; on a clean completion, a user cancel, a
     * driver dispose, and an agent handoff the detail is `undefined` — the historical shape,
     * kept byte-identical so subscribers that only care about the boundary can keep ignoring
     * it. Structured-cloneable so it survives the cross-tab BroadcastChannel hop.
     *
     * A `'budget-exhausted'` failure additionally carries `vendor` — the concrete
     * vendor the walled turn resolved to (GENC-1464), which is NOT the same thing as
     * the registry alias recorded on the debug-log entry. Optional and additive: a
     * subscriber reading only `failureReason` is unaffected, and every other
     * failure still emits the historical `{ failureReason }` with no `vendor` key.
     * It exists so a later per-vendor budget model is an additive change rather
     * than a retrofit — the vendor is known at the transport and at the driver, and
     * was previously discarded between them.
     *
     * Note this topic is forwarded on the tab-scoped channel, so a wall hit in a
     * popped-out window reaches the main window's subscribers too — which is why
     * the assistant's blocked latch fires there as well. Correct for a shared spend
     * cap; see `docs/migration-GENC-1464.md` §Scope.
     */
    'tool-loop-end': {
        failureReason?: TurnFailureReason;
        vendor?: AIProviderType;
        /**
         * Proxy-reported spend figures, present only on `budget-exhausted`. Carried
         * here because this event — not the driver's return value — is what latches
         * the blocked state for a wall hit INSIDE the tool loop (the common case):
         * the publish happens in `sendMessage`'s `finally`, so it lands before the
         * return-value seam and wins the latch. Without these the banner would fall
         * back to the generic copy in exactly the path the figures were added for.
         * Plain numbers + string keep the detail structured-cloneable for the
         * cross-tab hop.
         */
        budget?: {
            budgetUsd?: number;
            spentUsd?: number;
            vendorLabel: string;
            /**
             * The refusing vendor as a typed value: normalised from `vendorLabel`
             * where a vendor claims that label, otherwise from the proxy's own
             * `vendor` field on the 402 — so it can disagree with `vendorLabel`,
             * which is what keeps attribution working behind a white-labelled or
             * multiplexing gateway.
             *
             * Distinct from the detail's top-level `vendor` (the driver's
             * last-resolved provider): this one comes from the transport that was
             * actually refused, so it is the one a per-vendor latch trusts first.
             */
            vendor?: AIProviderType;
            /**
             * The proxy's verdict on whether any OTHER vendor it meters still has
             * headroom. The one fact here a subscriber cannot work out for itself:
             * the registry says which vendors EXIST, never which still have
             * budget. A `false` is what stops the banner advising a switch to a
             * vendor that is equally spent.
             */
            otherVendorAvailable?: boolean;
        };
    } | undefined;
    /**
     * Fired when a tool handler hands a widget to the user mid-loop and parks awaiting it
     * (`requestInteraction`) — the turn is suspended between provider calls, with no request
     * in flight. Pairs with {@link AgenticActivityEvents.'interaction-resolved'}.
     *
     * This is the inverse boundary to {@link AgenticActivityEvents.'tool-loop-start'}: the
     * loop is running (still inside `tool-loop-start`/`tool-loop-end`) but is momentarily idle,
     * waiting on the user. Use it for hooks that are unsafe *while computing* but safe *while
     * parked* — e.g. enabling a control that must not change mid-request but is fine to change
     * during a long journey step. Tab-local (not forwarded cross-tab): the widget and its
     * waiting state belong to the tab that opened it.
     */
    'interaction-requested': undefined;
    /**
     * Fired when a parked widget interaction ends — by user completion, timeout, or
     * cancellation — just before the suspended tool handler resumes and the loop continues.
     * Pairs with {@link AgenticActivityEvents.'interaction-requested'}. After this the turn is
     * computing again (until `tool-loop-end`). Tab-local.
     */
    'interaction-resolved': undefined;
}
//# sourceMappingURL=ai-activity-channel.d.ts.map