import { z } from "zod"; /** * Comments: a note a person or an agent leaves on ONE ROW of a trace, in the * `agency logs` viewer or through `agency logs session comment add`. They are * not annotations: an annotation is an opinion about a trace as a whole with * a content-derived id and a fold that decides effective scores, while a * comment is about one row, has no score, and needs its own id. One * append-only `comments.jsonl` per run directory (or `.comments.jsonl` * beside a loose statelog); this module owns the row shape, the parse, and * the pure fold from rows to top-level comments with their replies, and the * one way a comments file is read (`readCommentsFile`). Writing is * `mutations.ts`'s. */ export type CommentAuthor = { kind: "human" | "agent"; id: string; }; /** Facts about the row that do not depend on the row-id format, so a comment * can still say what it was about if the id stops resolving: the row's * time, its thread, and the tool or model it names. */ export type Anchor = { at?: string; thread?: string; name?: string; }; export type Comment = { v: 1; id: string; traceId: string; rowId: string; anchor: Anchor; author: CommentAuthor; text: string; created: string; /** The comment this one answers; an agent's reply to a person's question. */ replyTo?: string; }; export type CommentDraft = Omit; export declare const CommentSchema: z.ZodObject<{ v: z.ZodLiteral<1>; id: z.ZodString; traceId: z.ZodString; rowId: z.ZodString; anchor: z.ZodObject<{ at: z.ZodOptional; thread: z.ZodOptional; name: z.ZodOptional; }, z.core.$strip>; author: z.ZodObject<{ kind: z.ZodEnum<{ human: "human"; agent: "agent"; }>; id: z.ZodString; }, z.core.$strip>; text: z.ZodString; created: z.ZodString; replyTo: z.ZodOptional; }, z.core.$strict>; export type CommentParseError = { line: number; detail: string; }; /** Tolerant, like `readAnnotations`: a bad line is reported and skipped, and a * final line without its newline is a torn write and is ignored. */ export declare function parseCommentsJsonl(text: string): { rows: Comment[]; errors: CommentParseError[]; }; /** Every row of a comments file, with each bad line reported and skipped. * A missing file is no rows. */ export declare function readCommentsFile(commentsPath: string, reportWarning: (message: string) => void): Comment[]; /** A top-level comment with the replies that answer it, in file order. */ export type CommentThread = { comment: Comment; replies: Comment[]; }; export type FoldedComments = { /** In file order. A reply whose parent is not in the file is listed on * its own, so nothing anyone wrote disappears. */ threads: CommentThread[]; }; export declare function foldComments(rows: readonly Comment[]): FoldedComments; export declare function threadsForTrace(folded: FoldedComments, traceId: string): CommentThread[]; /** How a comment reads to someone (or a model) who cannot look the row up: * `reviewer ยท gpt-5 call: why does it read the config a second time?`. */ export declare function anchorText(anchor: Anchor): string; export declare function commentWithAnchor(comment: Comment): string;