/**
 * Messages slot subflow builder
 *
 * Pattern: Builder (returns a FlowChart mountable via addSubFlowChartNext).
 * Role:    Layer-3 context engineering. Produces InjectionRecord[] from
 *          the current conversation history. For LLMCall, that's one
 *          user message. For Agent, it's user + assistant + tool-result
 *          messages accumulated over iterations.
 * Emits:   None directly; ContextRecorder sees the writes.
 *
 * ── What this slot is, and is not ───────────────────────────────────
 * It is the OBSERVABILITY PROJECTION of the conversation: one
 * InjectionRecord per message, with the source, reason, role and
 * recency a consumer needs to see what the turn was made of. It is not
 * the wire. The request's message list comes from `scope.history`
 * directly (`stages/callLLM.ts`), because the projection flattens away
 * the LLM-protocol shape a provider needs — an assistant turn's
 * `toolCalls[]`, a tool turn's `toolCallId`.
 *
 * Nothing enters the conversation HERE, and that is the point. Two stages
 * upstream edit `scope.history` before this one reads it: the window
 * strategy takes messages out (`stages/window.ts`, 7.16–7.17) and the
 * delivery stage lets declared ones in (`stages/deliver.ts`, 7.21). Both run
 * at the loop head, before the slots, so the projection and the wire always
 * describe the same past.
 *
 * That is why this file no longer walks `activeInjections` looking for
 * `inject.messages`. Until 7.19.1 it did, and it produced a record — an
 * emitted `context.injected` — for content the request never carried, which
 * is the exact bug the wire-truth test now guards. A delivered injection is
 * IN the window by the time this runs, so it is projected like any other
 * message and attributed to its injection by the `injectedBy` marker the
 * delivery stage stamped. One wire message, one record, one name.
 */
import type { FlowChart } from 'footprintjs';
import type { ContextRole, ContextSource } from '../../events/types.js';
/**
 * A single message supplied by the caller. Structurally matches the
 * LLMMessage adapter type but local-aliased to keep this file free of
 * adapter-layer coupling.
 */
export interface InputMessage {
    readonly role: ContextRole;
    readonly content: string;
    readonly toolCallId?: string;
    readonly toolName?: string;
    /** Set by the delivery stage on a message an Injection put here — the
     *  marker this slot attributes by. Mirrors `LLMMessage.injectedBy`. */
    readonly injectedBy?: {
        readonly injectionId: string;
        readonly flavor: ContextSource;
        readonly reason?: string;
        readonly iteration: number;
    };
}
export interface MessagesSlotConfig {
    /** Budget cap (chars). Default: 10000. Set from the public door as
     *  `contextBudget.messages` on `AgentOptions` / `LLMCallOptions`. */
    readonly budgetCap?: number;
}
/**
 * Build the Messages slot subflow.
 *
 * Mount with:
 *   builder.addSubFlowChartNext(SUBFLOW_IDS.MESSAGES, buildMessagesSlot(cfg), 'Messages', {
 *     inputMapper: (parent) => ({ messages: parent.messages, iteration: parent.iteration }),
 *     outputMapper: (sf) => ({ messagesInjections: sf.messagesInjections }),
 *   })
 */
export declare function buildMessagesSlot(config?: MessagesSlotConfig): FlowChart;
