{"version":3,"sources":["../src/writers/index.ts"],"names":[],"mappings":"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","file":"writers.mjs","sourcesContent":["import path from \"node:path\";\n\nimport {\n  preparePersistedInspectEventForWrite,\n  resolveTraceSafetyOptions,\n} from \"../trace-event-safety.js\";\nimport { appendTraceFile, mkdirTraceDir } from \"../trace-filesystem.js\";\nimport type { PersistedInspectEvent } from \"../types/persisted-inspect-event.js\";\nimport { getTraceFilePath } from \"../utils.js\";\n\nexport interface TraceWriterStats {\n  writtenEvents: number;\n  droppedEvents: number;\n  flushCount: number;\n  lastFlushAt?: string;\n  lastError?: string;\n}\n\nexport interface TraceWriter {\n  write(event: PersistedInspectEvent): Promise<void>;\n  flush?(): Promise<void>;\n  close?(): Promise<void>;\n  getStats?(): TraceWriterStats;\n}\n\nexport interface MemoryTraceWriter extends TraceWriter {\n  getEvents(): PersistedInspectEvent[];\n  clear(): void;\n}\n\nexport interface FileTraceWriterOptions {\n  /**\n   * Directory for per-run JSONL traces. Defaults to AgentInspect's default\n   * trace directory when neither `dir` nor `filePath` is supplied.\n   */\n  dir?: string;\n  /**\n   * Explicit JSONL output path. When supplied, all accepted events are written\n   * to this file rather than deriving a per-run file from `event.runId`.\n   */\n  filePath?: string;\n}\n\nexport type BufferedFileWriterOverflowMode = \"drop-oldest\" | \"drop-newest\";\n\nexport interface BufferedFileWriterOptions extends FileTraceWriterOptions {\n  /**\n   * Maximum number of events retained before overflow policy applies.\n   * Defaults to 1000.\n   */\n  maxQueueSize?: number;\n  /**\n   * Flush delay after the first queued event. Defaults to 250ms.\n   */\n  flushIntervalMs?: number;\n  /**\n   * Maximum events appended by one filesystem batch. Defaults to 100.\n   */\n  maxBatchSize?: number;\n  /**\n   * Overflow policy when `maxQueueSize` is reached. Defaults to `drop-oldest`.\n   */\n  overflow?: BufferedFileWriterOverflowMode;\n}\n\nexport interface CompositeTraceWriterOptions {\n  writers: TraceWriter[];\n}\n\nconst DEFAULT_TRACE_SAFETY = resolveTraceSafetyOptions();\n\nfunction createInitialStats(): TraceWriterStats {\n  return {\n    writtenEvents: 0,\n    droppedEvents: 0,\n    flushCount: 0,\n  };\n}\n\nfunction markFlush(stats: TraceWriterStats): void {\n  stats.flushCount += 1;\n  stats.lastFlushAt = new Date().toISOString();\n}\n\nfunction cloneStats(stats: TraceWriterStats): TraceWriterStats {\n  return { ...stats };\n}\n\nfunction normalizeError(error: unknown): string {\n  if (error instanceof Error && error.message.trim() !== \"\") {\n    return error.message;\n  }\n  if (typeof error === \"string\" && error.trim() !== \"\") {\n    return error;\n  }\n  return \"Unknown trace writer error\";\n}\n\nfunction recordDropped(stats: TraceWriterStats, error: unknown): void {\n  stats.droppedEvents += 1;\n  stats.lastError = normalizeError(error);\n}\n\nfunction prepareWriterEvent(\n  event: PersistedInspectEvent,\n): PersistedInspectEvent | undefined {\n  return preparePersistedInspectEventForWrite(event, DEFAULT_TRACE_SAFETY);\n}\n\nfunction resolveFilePath(\n  event: PersistedInspectEvent,\n  options: FileTraceWriterOptions,\n): string {\n  if (options.filePath && options.filePath.trim() !== \"\") {\n    return path.resolve(options.filePath);\n  }\n  return getTraceFilePath(event.runId, options.dir);\n}\n\nfunction serializeEvent(event: PersistedInspectEvent): string {\n  return `${JSON.stringify(event)}\\n`;\n}\n\nasync function appendEventLine(\n  event: PersistedInspectEvent,\n  options: FileTraceWriterOptions,\n): Promise<void> {\n  const filePath = resolveFilePath(event, options);\n  await mkdirTraceDir(path.dirname(filePath));\n  await appendTraceFile(filePath, serializeEvent(event));\n}\n\nasync function appendEventBatch(\n  events: PersistedInspectEvent[],\n  options: FileTraceWriterOptions,\n): Promise<{ written: number; dropped: number; lastError?: string }> {\n  const byPath = new Map<string, string[]>();\n  let dropped = 0;\n  let lastError: string | undefined;\n\n  for (const event of events) {\n    try {\n      const filePath = resolveFilePath(event, options);\n      const line = serializeEvent(event);\n      const lines = byPath.get(filePath);\n      if (lines) {\n        lines.push(line);\n      } else {\n        byPath.set(filePath, [line]);\n      }\n    } catch (error) {\n      dropped += 1;\n      lastError = normalizeError(error);\n    }\n  }\n\n  let written = 0;\n  for (const [filePath, lines] of byPath) {\n    try {\n      await mkdirTraceDir(path.dirname(filePath));\n      await appendTraceFile(filePath, lines.join(\"\"));\n      written += lines.length;\n    } catch (error) {\n      dropped += lines.length;\n      lastError = normalizeError(error);\n    }\n  }\n\n  return lastError\n    ? { written, dropped, lastError }\n    : { written, dropped };\n}\n\nexport function memoryWriter(): MemoryTraceWriter {\n  const events: PersistedInspectEvent[] = [];\n  const stats = createInitialStats();\n\n  return {\n    async write(event) {\n      const safe = prepareWriterEvent(event);\n      if (safe === undefined) {\n        recordDropped(stats, \"Invalid persisted inspect event\");\n        return;\n      }\n      events.push(safe);\n      stats.writtenEvents += 1;\n    },\n    async flush() {\n      markFlush(stats);\n    },\n    async close() {\n      // Memory writer has no external resources. Keep close idempotent.\n    },\n    getStats() {\n      return cloneStats(stats);\n    },\n    getEvents() {\n      return events.map((event) => structuredClone(event));\n    },\n    clear() {\n      events.length = 0;\n    },\n  };\n}\n\nexport function nullWriter(): TraceWriter {\n  const stats = createInitialStats();\n\n  return {\n    async write() {\n      stats.writtenEvents += 1;\n    },\n    async flush() {\n      markFlush(stats);\n    },\n    async close() {\n      // Null writer has no external resources. Keep close idempotent.\n    },\n    getStats() {\n      return cloneStats(stats);\n    },\n  };\n}\n\nexport function fileWriter(options: FileTraceWriterOptions = {}): TraceWriter {\n  const stats = createInitialStats();\n  let closed = false;\n  let queue: Promise<void> = Promise.resolve();\n\n  const enqueue = (event: PersistedInspectEvent): Promise<void> => {\n    const operation = queue.then(async () => {\n      if (closed) {\n        recordDropped(stats, \"Trace writer is closed\");\n        return;\n      }\n      try {\n        await appendEventLine(event, options);\n        stats.writtenEvents += 1;\n      } catch (error) {\n        recordDropped(stats, error);\n      }\n    });\n\n    queue = operation.catch(() => {\n      // Individual operations are already isolated above. This catch keeps the\n      // internal queue alive even if an unexpected implementation error slips\n      // through.\n    });\n\n    return operation.catch(() => {\n      // Instrumentation failures must not replace application errors.\n    });\n  };\n\n  return {\n    write(event) {\n      const safe = prepareWriterEvent(event);\n      if (safe === undefined) {\n        recordDropped(stats, \"Invalid persisted inspect event\");\n        return Promise.resolve();\n      }\n      return enqueue(safe);\n    },\n    async flush() {\n      await queue;\n      markFlush(stats);\n    },\n    async close() {\n      if (closed) return;\n      await queue;\n      closed = true;\n    },\n    getStats() {\n      return cloneStats(stats);\n    },\n  };\n}\n\nfunction positiveInteger(value: number | undefined, fallback: number): number {\n  if (value === undefined) return fallback;\n  if (!Number.isFinite(value) || value <= 0) return fallback;\n  return Math.floor(value);\n}\n\nfunction nonNegativeInteger(value: number | undefined, fallback: number): number {\n  if (value === undefined) return fallback;\n  if (!Number.isFinite(value) || value < 0) return fallback;\n  return Math.floor(value);\n}\n\nexport function bufferedFileWriter(\n  options: BufferedFileWriterOptions = {},\n): TraceWriter {\n  const stats = createInitialStats();\n  const maxQueueSize = positiveInteger(options.maxQueueSize, 1000);\n  const flushIntervalMs = nonNegativeInteger(options.flushIntervalMs, 250);\n  const maxBatchSize = positiveInteger(options.maxBatchSize, 100);\n  const overflow = options.overflow ?? \"drop-oldest\";\n  const pending: PersistedInspectEvent[] = [];\n  let closed = false;\n  let timer: ReturnType<typeof setTimeout> | undefined;\n  let chain: Promise<void> = Promise.resolve();\n\n  const clearTimer = (): void => {\n    if (timer !== undefined) {\n      clearTimeout(timer);\n      timer = undefined;\n    }\n  };\n\n  const scheduleFlush = (): void => {\n    if (closed || timer !== undefined || pending.length === 0) return;\n    timer = setTimeout(() => {\n      timer = undefined;\n      void drain(false);\n    }, flushIntervalMs);\n    if (\n      timer &&\n      typeof timer === \"object\" &&\n      \"unref\" in timer &&\n      typeof timer.unref === \"function\"\n    ) {\n      timer.unref();\n    }\n  };\n\n  const drainBatch = async (drainAll: boolean): Promise<void> => {\n    clearTimer();\n    do {\n      const batch = pending.splice(0, maxBatchSize);\n      if (batch.length === 0) break;\n      const result = await appendEventBatch(batch, options);\n      stats.writtenEvents += result.written;\n      stats.droppedEvents += result.dropped;\n      if (result.lastError) {\n        stats.lastError = result.lastError;\n      }\n    } while (drainAll && pending.length > 0);\n    if (pending.length > 0) scheduleFlush();\n  };\n\n  const drain = (drainAll: boolean): Promise<void> => {\n    const operation = chain.then(() => drainBatch(drainAll));\n    chain = operation.catch(() => {\n      // Keep later flushes alive even if an unexpected implementation error\n      // escapes the batch isolation above.\n    });\n    return operation.catch(() => {\n      // Instrumentation failures must not replace application errors.\n    });\n  };\n\n  return {\n    async write(event) {\n      if (closed) {\n        recordDropped(stats, \"Trace writer is closed\");\n        return;\n      }\n\n      const safe = prepareWriterEvent(event);\n      if (safe === undefined) {\n        recordDropped(stats, \"Invalid persisted inspect event\");\n        return;\n      }\n\n      if (pending.length >= maxQueueSize) {\n        if (overflow === \"drop-newest\") {\n          recordDropped(stats, \"Trace writer queue overflow\");\n          return;\n        }\n        pending.shift();\n        recordDropped(stats, \"Trace writer queue overflow\");\n      }\n\n      try {\n        pending.push(safe);\n      } catch (error) {\n        recordDropped(stats, error);\n        return;\n      }\n\n      scheduleFlush();\n    },\n    async flush() {\n      await drain(true);\n      markFlush(stats);\n    },\n    async close() {\n      if (closed) return;\n      await drain(true);\n      closed = true;\n      clearTimer();\n    },\n    getStats() {\n      return cloneStats(stats);\n    },\n  };\n}\n\nexport function compositeWriter(\n  writersOrOptions: TraceWriter[] | CompositeTraceWriterOptions,\n): TraceWriter {\n  const stats = createInitialStats();\n  const writers = Array.isArray(writersOrOptions)\n    ? [...writersOrOptions]\n    : [...writersOrOptions.writers];\n  let closed = false;\n\n  const recordChildFailure = (error: unknown): void => {\n    stats.droppedEvents += 1;\n    stats.lastError = normalizeError(error);\n  };\n\n  return {\n    async write(event) {\n      if (closed) {\n        recordDropped(stats, \"Trace writer is closed\");\n        return;\n      }\n\n      const safe = prepareWriterEvent(event);\n      if (safe === undefined) {\n        recordDropped(stats, \"Invalid persisted inspect event\");\n        return;\n      }\n\n      const childResults = await Promise.all(\n        writers.map(async (writer) => {\n          try {\n            await writer.write(structuredClone(safe));\n            return true;\n          } catch (error) {\n            recordChildFailure(error);\n            return false;\n          }\n        }),\n      );\n\n      if (childResults.some(Boolean)) {\n        stats.writtenEvents += 1;\n      } else {\n        recordDropped(stats, \"No composite trace writer accepted the event\");\n      }\n    },\n    async flush() {\n      await Promise.all(\n        writers.map(async (writer) => {\n          try {\n            await writer.flush?.();\n          } catch (error) {\n            stats.lastError = normalizeError(error);\n          }\n        }),\n      );\n      markFlush(stats);\n    },\n    async close() {\n      if (closed) return;\n      await Promise.all(\n        writers.map(async (writer) => {\n          try {\n            await writer.close?.();\n          } catch (error) {\n            stats.lastError = normalizeError(error);\n          }\n        }),\n      );\n      closed = true;\n    },\n    getStats() {\n      return cloneStats(stats);\n    },\n  };\n}\n"]}