import type { IsoTime } from './common.js'; /** Opaque, stable, URL-safe ticket id: lowercase SHA-256 hex of * `canonicalRoot + "\0" + ticketBasename`. Clients must treat it as opaque — * it discloses no home filesystem path. */ export type InboxTicketIdDTO = string; export type InteractionKindDTO = 'notify' | 'decision' | 'context' | 'error' | 'review'; export interface DeckSourceDTO { sessionName?: string; askedBy?: string; blockedSince?: IsoTime; nodeId?: string; visual?: 'humanloop.visual/v1'; } export interface DeckTicketSummaryDTO { ticket_id: InboxTicketIdDTO; kind: 'deck'; title: string; subtitle: string; blocked_since: IsoTime; source: DeckSourceDTO; interaction_kind?: InteractionKindDTO; } export interface ReviewTicketSummaryDTO { ticket_id: InboxTicketIdDTO; kind: 'review'; title: string; subtitle: string; blocked_since: IsoTime; source: DeckSourceDTO; } export type InboxTicketSummaryDTO = DeckTicketSummaryDTO | ReviewTicketSummaryDTO; /** `GET /v1/human/inbox` result. `tickets` is sorted newest `blocked_since` * first, then `ticket_id` ascending. */ export interface InboxListDTO { tickets: InboxTicketSummaryDTO[]; } export interface InteractionOptionDTO { id: string; label: string; description?: string; } export interface InteractionPreAnswerDTO { selectedOptionId?: string; selectedOptionIds?: string[]; freetext?: string; label?: string; } export interface InteractionDTO { id: string; title: string; subtitle: string; /** Resolved source Markdown — `bodyPath` is deliberately impossible here. */ body?: string; options: InteractionOptionDTO[]; multiSelect?: boolean; allowFreetext?: boolean; freetextLabel?: string; kind?: InteractionKindDTO; preAnswered?: InteractionPreAnswerDTO; } export interface DeckDTO { title: string; source?: DeckSourceDTO; interactions: InteractionDTO[]; } /** `GET /v1/human/inbox/:ticket_id` result for a pending deck. */ export interface InboxDeckDTO { ticket_id: InboxTicketIdDTO; kind: 'deck'; deck: DeckDTO; } export interface InteractionResponseDTO { id: string; selectedOptionId?: string; selectedOptionIds?: string[]; freetext?: string; optionComments?: Record; } /** `POST /v1/human/inbox/:ticket_id/respond` body. */ export interface RespondInboxDeckRequest { responses: InteractionResponseDTO[]; } /** `POST /v1/human/inbox/:ticket_id/respond` result — the canonical humanloop * `humanloop.response/v2` result, unchanged. */ export interface DeckTicketResultDTO { schema: 'humanloop.response/v2'; kind: 'deck'; responses: InteractionResponseDTO[]; summary: string; completedAt: IsoTime; } /** `POST /v1/human/inbox/:ticket_id/cancel` body. `reason`, when present, must * be nonempty after trim and at most 1000 characters. */ export interface CancelInboxTicketRequest { reason?: string; } /** `POST /v1/human/inbox/:ticket_id/cancel` result — the canonical humanloop * `humanloop.cancel/v1` result, unchanged. `actor` is always `"human"`. */ export interface CanceledTicketResultDTO { schema: 'humanloop.cancel/v1'; kind: 'canceled'; canceledAt: IsoTime; reason?: string; actor?: string; }