/** * L2 — the reducer: messages are a PURE projection of the event log. * * ADR-0002 says the log is the single truth. These two functions are what * make that claim enforceable: `projectMessages(log.all)` rebuilds the exact * message array the loop hands to the adapter, and `messagesToEvents` * encodes seed history into the log. Round-trip property: * `projectMessages(messagesToEvents(m)) === m` — pinned by tests, and * LOSSLESS (Area 6): `source`, `tags`, image content blocks, and assistant * text-block boundaries survive the round trip. * * The loop no longer keeps a parallel `messages` array: every adapter call * derives from the log, so there is one store and the replay of `seq` 0..N * reproduces the run exactly. * * Events with no message shape (usage, stop, thinking, terminal, the * compaction events' own records) are skipped by the projection; * `compacted` applies the EXACT persisted replacements verbatim — it never * re-runs the compaction algorithm (a future version could differ, A group/D * group); `microcompacted` boundaries re-derive the cleared view from the * stream itself (deterministic and idempotent); `summarized` (ADR-0044) * replaces its covered range with one USER message carrying the summary * behind SUMMARY_FRAMING (E6's boundary honesty — see that constant * below; it is deliberately NOT an assistant message). All three are * persisted facts — the replay equals the live run. See ADR-0002. */ import type { Event } from "../protocol/events.js"; import type { EventInput } from "./event-log.js"; import type { AssistantBlock, Message, MessageSource } from "../protocol/messages.js"; /** * C area: tools whose output is eligible for microcompact clearing — reads, * listings, searches, and shell output. write/edit outputs are short and * never cleared. Exported so the loop's boundary computation (bootstrap #3) * counts exactly the results the projection can clear. */ export declare const MICROCOMPACTABLE: Set; /** The tag that makes a tool result un-clearable (C area). */ export declare const DO_NOT_COMPACT = "do-not-compact"; /** E6 (e) — the summary renders as a USER message with this framing (the * boundary honesty): the model reads the compressed history as context, * not as a reply it produced. The text rides verbatim after the frame — * no transcript path pointer (the workspace jail would refuse a path * outside cwd; transcript recall is a separate surface). */ export declare const SUMMARY_FRAMING = "The previous conversation history has been compressed into the summary below. Recent messages are kept verbatim."; /** * Rebuild the message array from events. Deterministic and order-sensitive: * replaying the same log always produces the same messages — BYTE FOR BYTE * (D area): the same event prefix derives the same message prefix; the only * events that change already-derived messages are `microcompacted` * boundaries and `summarized` facts, which are themselves persisted facts * (their replay derives the same projection every time). * * Text block boundaries are preserved: `text_end` closes the current text * block (an explicit boundary); `text_start` after a block opens a new one. * A stream of deltas WITHOUT `text_end` (the adapters' common shape) closes * at the next block/tool/result boundary. */ export declare function projectMessages(events: readonly (Event | EventInput)[]): readonly Message[]; /** * Encode seed messages into log events — LOSSLESSLY for the framework's own * shapes (Area 6): one `text_delta` per text block (boundaries preserved), * `source` on the first event of each message, `tags` on tool results, * content blocks passed through. Nothing a legal Message can express is * dropped. */ export declare function messagesToEvents(messages: readonly Message[]): EventInput[]; export type { AssistantBlock, MessageSource };