406 lines · 12.2 KB · TypeScript
RawDownload
/** * Type definitions for the new chat history architecture. * These types separate user input from AI responses for a chat-style display. */ import type {  ParsedMessage,  Process,  SemanticStep,  SessionMetrics,  ToolUseResultData,} from './data';export type { SemanticStep };import type { ClaudeMdStats } from './claudeMd';import type { CompactionTokenDelta } from './contextInjection';import type { ModelInfo } from '@shared/utils/modelParser'; // =============================================================================// Expansion Levels// ============================================================================= /** * AI Group expansion levels for the collapsible UI. * - collapsed: Show only summary line "1 tool call, 3 messages" * - items: Show list of items (thinking, tool calls, etc.) * - full: Show full content of each item */export type AIGroupExpansionLevel = 'collapsed' | 'items' | 'full'; // =============================================================================// User Group Types// ============================================================================= /** * Command reference extracted from user input (e.g., /isolate-context, /context). */export interface CommandInfo {  /** Command name without slash (e.g., "isolate-context") */  name: string;  /** Optional arguments after the command */  args?: string;  /** Full raw text including slash */  raw: string;  /** Position in the text where command starts */  startIndex: number;  /** Position in the text where command ends */  endIndex: number;} /** * Image data from user message. */export interface ImageData {  /** Unique identifier */  id: string;  /** MIME type */  mediaType: 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp';  /** Base64 encoded data for display */  data?: string;} /** * File reference mentioned in user message (e.g., @file.ts). */export interface FileReference {  /** File path */  path: string;  /** Optional line range */  lineRange?: {    start: number;    end?: number;  };  /** Raw text as written */  raw: string;} /** * Parsed content from a user message. */export interface UserGroupContent {  /** Plain text content (with commands removed for display) */  text?: string;  /** Raw text content (original) */  rawText?: string;  /** Extracted commands */  commands: CommandInfo[];  /** Extracted images */  images: ImageData[];  /** Extracted file references */  fileReferences: FileReference[];} /** * User Group - represents a user's complete input. * This is one side of a conversation turn. */export interface UserGroup {  /** Unique identifier */  id: string;  /** Original ParsedMessage */  message: ParsedMessage;  /** Timestamp of the message */  timestamp: Date;  /** Parsed content */  content: UserGroupContent;  /** Index within the session (for ordering) */  index: number;} /** * System Group - represents command output rendered like AI. */export interface SystemGroup {  id: string;  message: ParsedMessage;  timestamp: Date;  commandOutput: string; // Raw output text  commandName?: string; // Optional: extracted command name} // =============================================================================// AI Group Types// ============================================================================= /** * Summary statistics for the collapsed AI Group view. */export interface AIGroupSummary {  /** Preview of thinking content (first ~100 chars) */  thinkingPreview?: string;  /** Number of tool calls in this group */  toolCallCount: number;  /** Number of output messages */  outputMessageCount: number;  /** Number of subagent executions */  subagentCount: number;  /** Total duration in milliseconds */  totalDurationMs: number;  /** Total tokens used */  totalTokens: number;  /** Output tokens */  outputTokens: number;  /** Cached tokens */  cachedTokens: number;} /** * Linked tool item pairing a tool call with its result. * Includes preview text for display in collapsed/item views. */export interface LinkedToolItem {  /** Tool call ID */  id: string;  /** Tool name */  name: string;  /** Tool input parameters */  input: Record<string, unknown>;  /**   * Token count for the tool CALL (what Claude generated).   * From message.usage.output_tokens, proportioned if multiple tools in message.   * For Write: includes file content. For Edit: includes old_string + new_string.   */  callTokens?: number;  /** Tool result if received */  result?: {    content: string | unknown[];    isError: boolean;    toolUseResult?: ToolUseResultData;    /** Pre-computed token count for the result content */    tokenCount?: number;  };  /** Preview of input (first 100 chars) */  inputPreview: string;  /** Preview of output (first 200 chars) */  outputPreview?: string;  /** When the tool was called */  startTime: Date;  /** When the result was received */  endTime?: Date;  /** Duration in milliseconds */  durationMs?: number;  /** Whether this is an orphaned call (no result) */  isOrphaned: boolean;  /** Model used for the assistant message containing this tool call */  sourceModel?: string;  /**   * Skill instructions content for Skill tool calls.   * Contains the follow-up text message starting with "Base directory for this skill:".   * This is captured from isMeta:true user messages with matching sourceToolUseID.   */  skillInstructions?: string;  /** Pre-computed token count for skill instructions */  skillInstructionsTokenCount?: number;} /** * Unified slash item - represents any slash command invocation. * All slash commands follow the same format: *   <command-name>/xxx</command-name> *   <command-message>xxx</command-message> *   <command-args>optional</command-args> * * This includes: * - Skills (e.g., /isolate-context) * - Built-in commands (e.g., /model, /context) * - Plugin commands * - MCP commands * - User-defined commands */export interface SlashItem {  /** Unique ID (generated from command message uuid) */  id: string;  /** Slash name extracted from <command-name>/xxx</command-name> */  name: string;  /** Message content from <command-message> */  message?: string;  /** Optional arguments from <command-args> */  args?: string;  /** The command message uuid */  commandMessageUuid: string;  /** Instructions/output content (from follow-up isMeta:true message with parentUuid) */  instructions?: string;  /** Pre-computed token count for instructions */  instructionsTokenCount?: number;  /** Timestamp of the command message */  timestamp: Date;} /** * Teammate message received from a team member agent. */export interface TeammateMessage {  id: string;  teammateId: string;  color: string;  summary: string;  content: string;  timestamp: Date;  tokenCount?: number;  /** Summary of the SendMessage that triggered this response (reply context) */  replyToSummary?: string;  /** Tool call ID of the SendMessage that triggered this response */  replyToToolId?: string;} /** * Display item for the AI Group - union of possible items to show. * These are flattened and shown in chronological order. */export type AIGroupDisplayItem =  | { type: 'thinking'; content: string; timestamp: Date; tokenCount?: number }  | { type: 'tool'; tool: LinkedToolItem }  | { type: 'subagent'; subagent: Process }  | { type: 'output'; content: string; timestamp: Date; tokenCount?: number }  | { type: 'slash'; slash: SlashItem }  | { type: 'teammate_message'; teammateMessage: TeammateMessage }  | { type: 'subagent_input'; content: string; timestamp: Date; tokenCount?: number }  | {      type: 'compact_boundary';      content: string;      timestamp: Date;      tokenDelta?: CompactionTokenDelta;      phaseNumber: number;    }; /** * The last output in an AI Group - what user sees as "the answer". * Either text output, the last tool result, an interruption, ongoing (still in progress), * or plan_exit (ExitPlanMode tool call with plan content). */export interface AIGroupLastOutput {  /** Output type */  type: 'text' | 'tool_result' | 'interruption' | 'ongoing' | 'plan_exit';  /** Text content if type === 'text' */  text?: string;  /** Tool name if type === 'tool_result' */  toolName?: string;  /** Tool result content if type === 'tool_result' */  toolResult?: string;  /** Whether the tool result was an error */  isError?: boolean;  /** Interruption message text if type === 'interruption' */  interruptionMessage?: string;  /** Plan content if type === 'plan_exit' (from ExitPlanMode tool input) */  planContent?: string;  /** Preamble text before plan exit (e.g., "The plan is complete. Let me exit plan mode...") */  planPreamble?: string;  /** Timestamp of this output */  timestamp: Date;} /** * Enhanced AI Group with display-ready data for the new UI. * Extends the base AIGroup with computed properties for rendering. */export interface EnhancedAIGroup extends AIGroup {  /** The last visible output (text or tool result) */  lastOutput: AIGroupLastOutput | null;  /** Flattened display items in chronological order */  displayItems: AIGroupDisplayItem[];  /** Map of tool call IDs to linked tool items */  linkedTools: Map<string, LinkedToolItem>;  /** Human-readable summary of items (e.g., "2 thinking, 4 tool calls, 3 subagents") */  itemsSummary: string;  /** Model used by main agent (most common if mixed) */  mainModel: ModelInfo | null;  /** Unique models used by subagents (if different from main) */  subagentModels: ModelInfo[];  /** CLAUDE.md injection statistics for this group */  claudeMdStats: ClaudeMdStats | null;} /** * Status of an AI Group. */export type AIGroupStatus = 'complete' | 'interrupted' | 'error' | 'in_progress'; /** * Token metrics for an AI Group. */export interface AIGroupTokens {  input: number;  output: number;  cached: number;  thinking?: number;} /** * AI Group - represents a single assistant response cycle. * AI Groups are independent items in the flat conversation list. */export interface AIGroup {  /** Unique identifier */  id: string;  /** 0-based index of this AI group within the session (for turn navigation) */  turnIndex: number;  /** Start timestamp */  startTime: Date;  /** End timestamp */  endTime: Date;  /** Duration in milliseconds */  durationMs: number;  /** Semantic steps within this response */  steps: SemanticStep[];  /** Token metrics */  tokens: AIGroupTokens;  /** Summary for collapsed view */  summary: AIGroupSummary;  /** Completion status */  status: AIGroupStatus;  /** Associated processes */  processes: Process[];  /** Source chunk ID */  chunkId: string;  /** Metrics for this AI response (summed across all messages) */  metrics: SessionMetrics;  /** All response messages (assistant + internal user messages) for accessing raw usage data */  responses: ParsedMessage[];  /** Whether this is the last AI group in an ongoing session */  isOngoing?: boolean;} // =============================================================================// Conversation Types// ============================================================================= /** * Compact Group - marks where conversation was compacted. * Contains the compact summary message with the conversation summary. */export interface CompactGroup {  id: string;  timestamp: Date;  message: ParsedMessage; // Contains compact summary in message.content  tokenDelta?: CompactionTokenDelta;  startingPhaseNumber?: number;} /** * Chat item - can be user, system, ai, or compact. * These are INDEPENDENT items in a flat list, not paired turns. */export type ChatItem =  | { type: 'user'; group: UserGroup }  | { type: 'system'; group: SystemGroup }  | { type: 'ai'; group: AIGroup }  | { type: 'compact'; group: CompactGroup }; /** * Session conversation as a flat list of independent chat items. * NO LONGER uses turns - each item stands alone. */export interface SessionConversation {  /** Session ID */  sessionId: string;  /** All chat items in chronological order */  items: ChatItem[];  /** Total count of user groups */  totalUserGroups: number;  /** Total count of system groups */  totalSystemGroups: number;  /** Total count of AI groups */  totalAIGroups: number;  /** Total count of compact groups */  totalCompactGroups: number;}