UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

103 lines (102 loc) • 6.82 kB
/** What ONE landed compaction did to the transcript, recorded at its commit point. */ export interface CompactionEffect { /** The entry ids that went into the summarized prefix (everything before `firstKeptEntryId`), or * `"unknown"` when the kept-tail anchor could not be located in the branch — the conservative * reading is that the whole branch was summarized, so a reader treats `"unknown"` as "every * receipt this run holds is invalidated" (the same direction * {@link import("./auto-compaction.js").countSummarizedCrossSessionMessages} already takes). */ readonly summarizedEntryIds: ReadonlySet<string> | "unknown"; } /** * One receipt ASK: the carrier a frame rides, and — for a frame that rides a TOOL RESULT — the * text {@link frameSurvivesInToolResult} must find in that result as committed. An injected frame is its * own carrier (the committed message IS the frame), so it carries no text to check. */ export interface FrameReceiptAsk { /** The injection queue's dedup key of the frame itself, or {@link toolResultReceiptKey} of the call whose result carries it. */ readonly carrier: string; readonly frameText?: string; } /** * The leg's settlement seam, one cell per run. * * `awaiting` is an ASK, not a log: only keys a consumer registered are ever given a receipt, an ask * leaves when its carrier commits, so a run that delivers thousands of ordinary notification frames * does not accumulate one map entry per frame. The key is the consumer's per-frame key. */ export interface FrameSettlement { /** Receipt asks a consumer is waiting on (key → ask). The receipt sink records nothing for any other key. */ readonly awaiting: Map<string, FrameReceiptAsk>; /** Receipts collected for awaited keys: key → the transcript entry id the frame landed in. */ readonly receipts: Map<string, string>; /** Awaited keys whose carrier COMMITTED WITHOUT the frame and nothing the HOST did explains it (an engine-side * crop): shown nothing, so owed again — never a receipt. */ readonly withheld: Set<string>; /** Carriers whose result a HOST hook rewrote (`postToolUse.updatedOutput`) before the commit — recorded only * for a carrier some ask rides ({@link noteHostRewrite}), consumed by the receipt at its commit: a frame the * rewrite kept gets an ordinary receipt, a frame it removed is host-withheld. */ readonly hostRewritten: Set<string>; /** Awaited keys whose frame is not in the host's rewrite (removed, truncated, or reshaped beyond whitespace): the * host decided what the model reads, so the consumer settles the record as the host's decision (terminal), * discloses it loudly, and never hands it over again. */ readonly hostWithheld: Set<string>; /** Compactions that LANDED this run and have not been consumed by a settlement pass yet, in landing * order. Recorded only while {@link FrameSettlement.wantsEffects} says a record could still be * broken by one, and cleared by the consumer's LOCAL settlement half — which needs no lease, so an * unclaimable or empty box cannot leave them piling up for the whole leg. */ readonly compactions: CompactionEffect[]; /** * #1036 — "is this engine frame's record still parked in a DURABLE box?" Set by the * session-box drain when it binds. The terminal sweep hands back engine-note payloads that never * drained and the runner pends them PER SESSION (an in-process copy); for a frame whose record the * drain no longer acks on delivery, that copy would be a second source of truth — the box already * re-serves it to the session's next run. Absent (no drain bound) ⇒ the pre-1036 behavior, which is * correct there: nothing else holds those frames. */ boxBacked?: (payload: unknown) => boolean; /** * #1036 — "is there a record a landed compaction could still break?" Asked at the compaction * COMMIT beat, before an effect is recorded at all. Absent (no drain bound) or `false` ⇒ the effect * is not recorded: nothing would ever read it, and a leg that compacts many times would otherwise * hold every landing's entry-id set until it ended. */ wantsEffects?: () => boolean; } export declare function createFrameSettlement(): FrameSettlement; /** The carrier key of a TOOL RESULT (the `ReadInbox` pull face): its own domain, so it can never * collide with an injection queue dedup key. One tool result can carry SEVERAL frames, each asked for * under its own key with this carrier. */ export declare function toolResultReceiptKey(toolCallId: string): string; /** * THE rule for a frame that rides a TOOL RESULT: the result can be replaced (`postToolUse.updatedOutput`) * or cropped (the aggregate result budget) after the frame was handed to it, so handing it over proves * nothing — the frame counts as delivered only when its text is present in the result AS COMMITTED * (a string, or the text blocks, each read whole), compared with every whitespace run on both sides folded * to one space: a rewrite that only re-spaces, re-indents or re-wraps the frame kept it. Any other change * (a word, an escape, the case) did not. Before the commit, nothing is proven. The inbox receipt * below reads it; the listing ride (`prepare-listings.ts`) does not call it — it never commits announced * state at ride time, the conservative answer for a frame whose commit has not happened yet. */ export declare function frameSurvivesInToolResult(committedContent: unknown, frameText: string): boolean; /** The station that applies a HOST hook's `updatedOutput` marks the carrier — only when an ask rides it, so an * ordinary rewritten result leaves nothing behind. */ export declare function noteHostRewrite(seam: FrameSettlement, toolCallId: string): void; /** The receipt sink's ONE writer: every ask riding `carrier` is answered — a receipt when its frame is in * the committed content (or it is its own carrier); when it is not, host-withheld if a host hook rewrote the * carrier (the host's decision), withheld otherwise (owed again). */ export declare function recordFrameReceipt(seam: FrameSettlement, carrier: string, committedContent: unknown, entryId: string): void; /** The carrier a committed frame was riding, as the harness reports it at the transcript append — a tool * result with the content it was committed with (after every result transformation); a user-attachment frame by * its delivery record's key (`inputId`, `ordinal`). */ export type CommittedFrameCarrier = { kind: "engine_note"; payload: unknown; } | { kind: "tool_result"; toolCallId: string; content: unknown; } | { kind: "attachment"; inputId: string; ordinal: number; };