/**
 * ActivityFrame — structured event pushed from daemon to caller via `activityTo` sinks.
 *
 * When a component sends `$prompt` with `activityTo: [mount1, mount2, ...]`,
 * the daemon sends `$activity` messages carrying ActivityFrame payloads to each
 * sink via `sendToInbox` (which crosses root boundaries).
 *
 * See: ARCHITECTURE/AGENT-SYSTEM-V2.md §22 (ADR-022: Event-Driven Prompt Architecture)
 */

export interface ActivityFrame {
  /** Correlates frames to the originating prompt request. */
  requestId: string;
  /** Monotonically increasing sequence within a request. */
  seq: number;
  /** Unix epoch ms when the frame was created. */
  ts: number;
  /** Mount path of the agent/component that emitted the underlying event. */
  source: string;

  /** Root trace ID — one per user interaction, never changes (§7). */
  traceId?: string;
  /** Span ID — one per agent invocation, generated by SystemLlm. */
  spanId?: string;
  /** Parent span ID — links child span to parent in nested agent chains. */
  parentSpanId?: string;
  /** Conversation/session ID used for transcript threading. */
  sessionId?: string;
  /** Browser resume ID when the UI uses a stable `sess-*` identifier. */
  resumeId?: string;
  /** Principal that initiated the request. */
  principalId?: string;

  kind: 'prompt' | 'llm' | 'tool' | 'system';
  phase: ActivityPhase;

  /** Human-readable summary (e.g. "Querying flowpad-page.db"). */
  summary?: string;
  /** Target mount for tool calls. */
  target?: string;
  /** Operation name for tool calls. */
  op?: string;
  /** Detail payload (tool result, error message, response text, etc.). */
  data?: unknown;
  /** Elapsed time for completed phases. */
  durationMs?: number;
}

export type ActivityPhase =
  | 'accepted'
  | 'started'
  | 'thinking'
  | 'token'
  | 'tool-start'
  | 'tool-result'
  | 'output'
  | 'done'
  | 'error'
  | 'cancelled';

const TERMINAL_PHASES: ReadonlySet<string> = new Set(['done', 'error', 'cancelled']);

export function isTerminalPhase(phase: string): boolean {
  return TERMINAL_PHASES.has(phase);
}
