/**
 * writeMessages — write-side stage that persists new turn messages as
 * `MemoryEntry`s.
 *
 * Reads from scope:  `identity`, `turnNumber`, `newMessages`
 * Writes to store:   one entry per message, id = `msg-{turnNumber}-{index}`
 *
 * Every written entry carries `source.turn` + `source.identity` so
 * retrieval stages can later show "recalled from turn 5" with correct
 * cross-session provenance. A content-hash signature is also registered
 * via `store.recordSignature` so subsequent `seen()` calls recognize
 * near-duplicate content without loading the full entries.
 *
 * Why a deterministic `id` format?
 *   `msg-{turn}-{index}` lets write-then-re-write be idempotent: a stage
 *   that re-runs in the same turn (retries, resumable turns) overwrites
 *   the same id instead of growing history. For non-turn-scoped writes,
 *   pass a custom `idFrom` that produces whatever shape your app needs.
 *
 * PII / redaction:
 *   Message content is stored VERBATIM — a memory is the agent's working
 *   state, what a later run recalls, and no redaction policy scrubs it
 *   (`../redactRefusal.ts` says why `defineMemory({ redact })` is refused).
 *   An agent's `redact` keeps named values out of the RECORD of this stage
 *   (its commit, its `memory.*` events, the narrative); it does not change
 *   what the store holds. If messages that contain PII must not be stored,
 *   do not write them (a read-only memory, or none), or scrub them before
 *   they reach the store — a `MemoryStore` wrapper whose `put` does it.
 *
 * Extended thinking blocks (Anthropic) / reasoning tokens (OpenAI):
 *   Persisting reasoning blocks is expensive — they can be 10-100× the
 *   size of the final message. Strip them from `scope.newMessages` before
 *   calling this stage UNLESS you plan to recall them (e.g. for debugging
 *   replay). A common pattern: write reasoning to `tier: 'cold'` with a
 *   short `ttlMs` so they age out quickly.
 */
import type { TypedScope } from 'footprintjs';
import type { MemoryStore } from '../store/index.js';
import type { LLMMessage as Message } from '../../provider-contract/types.js';
import type { MemoryState } from './types.js';
export interface WriteMessagesConfig {
    /** The store to persist to. */
    readonly store: MemoryStore;
    /**
     * Optional id producer — receives (turn, index, message) and returns
     * the `MemoryEntry.id`. Defaults to `msg-{turn}-{index}` which makes
     * re-runs of the same turn idempotent. Override for app-level ids
     * (e.g. use a message's server-side id).
     */
    readonly idFrom?: (turn: number, index: number, message: Message) => string;
    /**
     * Optional signature producer for the recognition set. When present,
     * each message produces a signature that is registered via
     * `store.recordSignature`; `seen()` later returns `true` for the same
     * content. Default: skip (many apps don't need recognition).
     */
    readonly signatureFrom?: (message: Message) => string;
    /**
     * Optional TTL in milliseconds from `Date.now()`. When set, written
     * entries expire this long after they were stored. Useful for
     * compliance retention windows ("delete chat history after 30 days").
     */
    readonly ttlMs?: number;
    /**
     * Optional tier for the entries. Typical pattern:
     *   - `'hot'`  for the last few turns
     *   - `'warm'` for older turns
     *   - `'cold'` for archived
     * Stages in Layer 3+ can filter on tier. Omitting leaves entries
     * untiered (read stages still see them; tier-filtered reads skip them).
     */
    readonly tier?: 'hot' | 'warm' | 'cold';
}
export declare function writeMessages(config: WriteMessagesConfig): (scope: TypedScope<MemoryState>) => Promise<void>;
