@agent-inspect/mcp 4.3.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -399,6 +399,9 @@ function validateEvent(event) {
399
399
  case "step_completed": {
400
400
  return nonEmptyString(event.runId) && nonEmptyString(event.stepId) && (event.status === "success" || event.status === "error") && finiteNumber(event.endTime) && finiteNumber(event.durationMs) && optionalErrorInfo(event.error);
401
401
  }
402
+ case "outcome_observed": {
403
+ return nonEmptyString(event.runId) && nonEmptyString(event.outcomeId) && nonEmptyString(event.name) && nonEmptyString(event.expectation) && (event.status === "passed" || event.status === "failed" || event.status === "unknown" || event.status === "skipped") && finiteNumber(event.observedAt);
404
+ }
402
405
  default:
403
406
  return false;
404
407
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/summarize.ts","../../core/src/logs/redactor.ts","../../core/src/redaction-profiles.ts","../../core/src/types.ts","../../core/src/utils/duration.ts","../../core/src/utils.ts","../../core/src/storage.ts","../../core/src/trace-event-safety.ts","../../core/src/context.ts","../../core/src/terminal.ts","../../core/src/step.ts","../src/wrap.ts"],"names":["crypto","path","os","nanoid","formatDuration","mkdir","isRecord","appendFile","out","AsyncLocalStorage","chalk","endTime","durationMs"],"mappings":"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","file":"index.cjs","sourcesContent":["const DEFAULT_MAX_SUMMARY_LENGTH = 240;\n\nexport function summarizeMcpValue(\n value: unknown,\n maxLength = DEFAULT_MAX_SUMMARY_LENGTH,\n): string {\n let text: string;\n try {\n if (typeof value === \"string\") {\n text = value;\n } else {\n text = JSON.stringify(value);\n }\n } catch {\n text = String(value);\n }\n if (text.length <= maxLength) return text;\n return `${text.slice(0, Math.max(0, maxLength - 3))}...`;\n}\n\nexport function hashServerUrl(url: string): string {\n let hash = 0;\n for (let i = 0; i < url.length; i += 1) {\n hash = (hash * 31 + url.charCodeAt(i)) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n","import crypto from \"node:crypto\";\n\nimport type { RedactionRule } from \"../types/log-config.js\";\n\nexport const DEFAULT_REDACT_KEYS = [\n \"authorization\",\n \"cookie\",\n \"token\",\n \"apiKey\",\n \"password\",\n \"secret\",\n \"email\",\n] as const;\n\nexport interface RedactorOptions {\n rules?: RedactionRule[];\n /** Additional exact keys (case-insensitive) to redact in addition to defaults. */\n extraKeys?: readonly string[];\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction toKey(s: string): string {\n return s.toLowerCase();\n}\n\nfunction stableHash(value: string): string {\n const h = crypto.createHash(\"sha256\").update(value, \"utf8\").digest(\"hex\");\n return h.slice(0, 8);\n}\n\ntype CompiledRule =\n | { key: string; strategy: \"full\" }\n | { key: string; strategy: \"prefix\"; keep: number }\n | { key: string; strategy: \"hash\" };\n\nfunction compileRules(\n rules?: RedactionRule[],\n extraKeys?: readonly string[],\n): CompiledRule[] {\n const out = new Map<string, CompiledRule>();\n\n const set = (r: CompiledRule) => {\n const k = toKey(r.key);\n out.set(k, { ...r, key: k } as CompiledRule);\n };\n\n for (const k of DEFAULT_REDACT_KEYS) {\n set({ key: k, strategy: \"full\" });\n }\n\n for (const k of extraKeys ?? []) {\n if (typeof k === \"string\" && k.length > 0) {\n set({ key: k, strategy: \"full\" });\n }\n }\n\n for (const r of rules ?? []) {\n if (typeof r === \"string\") {\n set({ key: r, strategy: \"full\" });\n continue;\n }\n const key = r.key;\n if (r.strategy === \"full\") set({ key, strategy: \"full\" });\n if (r.strategy === \"hash\") set({ key, strategy: \"hash\" });\n if (r.strategy === \"prefix\") {\n set({ key, strategy: \"prefix\", keep: typeof r.keep === \"number\" ? r.keep : 8 });\n }\n }\n\n return [...out.values()];\n}\n\nexport class Redactor {\n readonly #rules: CompiledRule[];\n\n constructor(options?: RedactorOptions) {\n this.#rules = compileRules(options?.rules, options?.extraKeys);\n }\n\n redactValue(key: string, value: unknown): unknown {\n const k = toKey(key);\n const rule = this.#rules.find((r) => r.key === k);\n if (!rule) {\n return this.#redactNested(value);\n }\n\n if (rule.strategy === \"full\") return \"[REDACTED]\";\n const asString =\n typeof value === \"string\"\n ? value\n : typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\"\n ? String(value)\n : undefined;\n\n if (rule.strategy === \"prefix\") {\n if (asString === undefined) return \"[REDACTED]\";\n const keep = Math.max(0, Math.floor(rule.keep));\n return asString.length <= keep ? `${asString}…` : `${asString.slice(0, keep)}…`;\n }\n\n if (rule.strategy === \"hash\") {\n if (asString === undefined) return \"[HASH:unknown]\";\n return `[HASH:${stableHash(asString)}]`;\n }\n\n return this.#redactNested(value);\n }\n\n redactRecord(record: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(record)) {\n out[k] = this.redactValue(k, v);\n }\n return out;\n }\n\n #redactNested(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((v) => this.#redactNested(v));\n }\n if (isRecord(value)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n out[k] = this.redactValue(k, v);\n }\n return out;\n }\n return value;\n }\n}\n\n","import type { RedactionProfile } from \"./types.js\";\n\n/** Extra keys redacted under the `share` profile (in addition to {@link DEFAULT_REDACT_KEYS}). */\nexport const SHARE_PROFILE_EXTRA_KEYS = [\n \"userEmail\",\n \"customerEmail\",\n \"phone\",\n \"phoneNumber\",\n \"address\",\n \"ip\",\n \"ipAddress\",\n \"sessionId\",\n \"requestId\",\n \"correlationId\",\n \"decisionId\",\n \"groupId\",\n \"customerId\",\n \"userId\",\n \"accountId\",\n \"tenantId\",\n \"orgId\",\n \"organizationId\",\n \"traceId\",\n \"spanId\",\n \"parentSpanId\",\n] as const;\n\n/** Extra keys redacted under the `strict` profile (in addition to share keys). */\nexport const STRICT_PROFILE_EXTRA_KEYS = [\n \"prompt\",\n \"completion\",\n \"input\",\n \"output\",\n \"inputPreview\",\n \"outputPreview\",\n \"message\",\n \"messages\",\n \"transcript\",\n \"context\",\n \"document\",\n \"documents\",\n \"chunk\",\n \"chunks\",\n \"retrieval\",\n \"query\",\n] as const;\n\nexport interface ResolvedRedactionProfile {\n profile: RedactionProfile;\n extraKeys: readonly string[];\n maxMetadataValueLengthCap?: number;\n maxPreviewLengthCap?: number;\n}\n\n/** Resolves named profile behavior (keys + metadata string caps). */\nexport function resolveRedactionProfile(\n profile: RedactionProfile = \"local\",\n): ResolvedRedactionProfile {\n switch (profile) {\n case \"local\":\n return { profile: \"local\", extraKeys: [] };\n case \"share\":\n return {\n profile: \"share\",\n extraKeys: SHARE_PROFILE_EXTRA_KEYS,\n maxMetadataValueLengthCap: 500,\n maxPreviewLengthCap: 200,\n };\n case \"strict\":\n return {\n profile: \"strict\",\n extraKeys: [...SHARE_PROFILE_EXTRA_KEYS, ...STRICT_PROFILE_EXTRA_KEYS],\n maxMetadataValueLengthCap: 200,\n maxPreviewLengthCap: 80,\n };\n default:\n return { profile: \"local\", extraKeys: [] };\n }\n}\n\nfunction isPreviewKey(key: string): boolean {\n return key.toLowerCase().includes(\"preview\");\n}\n\n/**\n * Applies profile metadata string caps. User-provided lower limits are preserved.\n */\nexport function applyProfileMetadataCaps(\n maxMetadataValueLength: number,\n maxPreviewLength: number,\n resolved: ResolvedRedactionProfile,\n): { maxMetadataValueLength: number; maxPreviewLength: number } {\n let meta = maxMetadataValueLength;\n let preview = maxPreviewLength;\n\n if (resolved.maxMetadataValueLengthCap !== undefined) {\n meta = Math.min(meta, resolved.maxMetadataValueLengthCap);\n }\n if (resolved.maxPreviewLengthCap !== undefined) {\n preview = Math.min(preview, resolved.maxPreviewLengthCap);\n }\n\n return { maxMetadataValueLength: meta, maxPreviewLength: preview };\n}\n\nexport function truncateStringForProfile(\n value: string,\n key: string,\n maxMetadataValueLength: number,\n maxPreviewLength: number,\n): string {\n const max = isPreviewKey(key) ? maxPreviewLength : maxMetadataValueLength;\n if (max <= 0) return \"…\";\n if (value.length <= max) return value;\n return `${value.slice(0, max)}…`;\n}\n","import type { RedactionRule } from \"./types/log-config.js\";\n\n/**\n * Discriminator for what kind of work a {@link Step} represents.\n * `\"decision\"` captures agent branching/choices; other values cover runs, LLM calls, tools, and user-defined steps.\n */\nexport type StepType =\n | \"run\"\n | \"llm\"\n | \"tool\"\n | \"decision\"\n | \"logic\"\n | \"state\"\n | \"custom\";\n\n/** Lifecycle state of a single {@link Step}. */\nexport type StepStatus = \"running\" | \"success\" | \"error\";\n\n/** Lifecycle state of an entire {@link Run}. */\nexport type RunStatus = \"running\" | \"success\" | \"error\";\n\n/** Structured error attached to a run or step when status is `\"error\"`. */\nexport interface ErrorInfo {\n message: string;\n stack?: string;\n}\n\n/**\n * Optional token counts for a step (e.g. LLM usage).\n * Reserved for future roadmap; MVP does not compute or persist token usage.\n */\nexport interface TokenMetadata {\n input?: number;\n output?: number;\n total?: number;\n cached?: number;\n}\n\n/** Arbitrary structured fields for a step; safe extensions use string keys. */\nexport interface StepMetadata {\n model?: string;\n toolName?: string;\n tokens?: TokenMetadata;\n retryCount?: number;\n [key: string]: unknown;\n}\n\n/**\n * One traced agent run (root of an execution tree).\n * MVP intentionally omits `input` / `output` on the run to limit PII, secrets, and serialization risk.\n */\nexport interface Run {\n id: string;\n name: string;\n status: RunStatus;\n startTime: number;\n endTime?: number;\n durationMs?: number;\n error?: ErrorInfo;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * One node in the execution tree under a {@link Run}.\n * MVP intentionally omits `input` / `output`; capture/redaction may come in a later version.\n */\nexport interface Step {\n id: string;\n runId: string;\n parentId?: string;\n name: string;\n type: StepType;\n status: StepStatus;\n startTime: number;\n endTime?: number;\n durationMs?: number;\n error?: ErrorInfo;\n metadata?: StepMetadata;\n}\n\n/** Version of the JSONL trace line schema consumed by AgentInspect tooling. */\nexport type TraceSchemaVersion = \"0.1\";\n\n/**\n * Status for lightweight trace metadata extraction.\n * `\"unknown\"` means the file contained valid events but a run status could not be determined safely.\n */\nexport type TraceMetadataStatus = \"success\" | \"error\" | \"running\" | \"unknown\";\n\nexport interface TraceMetadata {\n runId: string;\n name?: string;\n status: TraceMetadataStatus;\n startedAt?: number;\n endedAt?: number;\n durationMs?: number;\n eventCount: number;\n filePath: string;\n fileSize: number;\n createdAt: Date;\n}\n\nexport interface RunSummary {\n runId: string;\n name?: string;\n status: TraceMetadataStatus;\n durationMs?: number;\n totalSteps: number;\n llmSteps: number;\n toolSteps: number;\n logicSteps: number;\n errorSteps: number;\n maxDepth: number;\n longestStep?: {\n name: string;\n durationMs: number;\n type: string;\n };\n totalTokens?: {\n input: number;\n output: number;\n /** Present only when every token-bearing step has a supplied or derivable total. */\n total?: number;\n /** Sum of supplied cached counts; cached is not added to total. */\n cached?: number;\n };\n}\n\n/** Fields shared by every persisted trace event line. */\nexport interface TraceEventBase {\n schemaVersion: TraceSchemaVersion;\n event: string;\n timestamp: number;\n}\n\n/** Emitted when a run begins. */\nexport interface RunStartedEvent extends TraceEventBase {\n event: \"run_started\";\n runId: string;\n name: string;\n startTime: number;\n metadata?: Record<string, unknown>;\n}\n\n/** Emitted when a run finishes successfully or with an error. */\nexport interface RunCompletedEvent extends TraceEventBase {\n event: \"run_completed\";\n runId: string;\n status: \"success\" | \"error\";\n endTime: number;\n durationMs: number;\n error?: ErrorInfo;\n}\n\n/** Emitted when a step begins (including nested steps under `parentId`). */\nexport interface StepStartedEvent extends TraceEventBase {\n event: \"step_started\";\n runId: string;\n stepId: string;\n parentId?: string;\n name: string;\n type: StepType;\n startTime: number;\n metadata?: StepMetadata;\n}\n\n/**\n * Emitted when a step finishes (success or failure).\n * Failures use `status: \"error\"` and optional {@link ErrorInfo}; there is no separate `step_failed` event in MVP.\n */\nexport interface StepCompletedEvent extends TraceEventBase {\n event: \"step_completed\";\n runId: string;\n stepId: string;\n status: \"success\" | \"error\";\n endTime: number;\n durationMs: number;\n error?: ErrorInfo;\n}\n\n/** Discriminated union of all MVP trace events written as JSONL lines. */\nexport type TraceEvent =\n | RunStartedEvent\n | RunCompletedEvent\n | StepStartedEvent\n | StepCompletedEvent;\n\n/** Named redaction presets for trace writing and share-safe exports (v1.3.0+). */\nexport type RedactionProfile = \"local\" | \"share\" | \"strict\";\n\n/** Optional correlation fields for grouping and cross-run tracing (v1.3.0+). */\nexport interface TraceCorrelationMetadata {\n correlationId?: string;\n requestId?: string;\n decisionId?: string;\n groupId?: string;\n}\n\n/** Options for `inspectRun()` and `maybeInspectRun()`. */\nexport interface InspectRunOptions extends TraceCorrelationMetadata {\n traceDir?: string;\n silent?: boolean;\n metadata?: Record<string, unknown>;\n /**\n * When `false`, runs `fn` with no trace file, no execution context, and no terminal output.\n * Omitted or `true` preserves default tracing behavior.\n */\n enabled?: boolean;\n /**\n * Redact sensitive metadata keys before writing JSONL. Default `true` (conservative keys).\n * Pass `false` to persist metadata as-is (explicit opt-out).\n */\n redact?: boolean | { rules?: RedactionRule[] };\n /**\n * Redaction preset for trace metadata. Default `local` (same keys as default redaction).\n * `share` and `strict` add extra key-based redaction and tighter string bounds.\n * Ignored when `redact: false`.\n */\n redactionProfile?: RedactionProfile;\n /** Max UTF-8 bytes for a serialized trace event line. Default 65536. */\n maxEventBytes?: number;\n /** Max length for string metadata values (non-preview keys). Default 2000. */\n maxMetadataValueLength?: number;\n /** Max length for preview-like metadata keys (contains `preview`). Default 500. */\n maxPreviewLength?: number;\n}\n\n/** Options passed when opening a logical step (implemented in a later step). */\nexport interface StepOptions {\n type?: StepType;\n metadata?: StepMetadata;\n}\n\n/** Options for `observe()` — same surface as {@link InspectRunOptions} in MVP. */\nexport type ObserveOptions = InspectRunOptions;\n\n/**\n * Resolved settings for the active run while tracing is enabled.\n * Populated by runtime code in a later step; defined here for `context.ts`.\n */\nexport interface ExecutionContext {\n runId: string;\n runName: string;\n traceDir: string;\n silent: boolean;\n metadata?: Record<string, unknown>;\n}\n\n/** Stack position of the step currently executing (used by future context tracking). */\nexport interface ActiveStepContext {\n stepId: string;\n parentId?: string;\n depth: number;\n}\n\nconst STEP_TYPES: readonly StepType[] = [\n \"run\",\n \"llm\",\n \"tool\",\n \"decision\",\n \"logic\",\n \"state\",\n \"custom\",\n] as const;\n\nconst STEP_STATUSES: readonly StepStatus[] = [\n \"running\",\n \"success\",\n \"error\",\n] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Returns true if `value` is one of the MVP {@link StepType} literals. */\nexport function isStepType(value: unknown): value is StepType {\n return (\n typeof value === \"string\" &&\n (STEP_TYPES as readonly string[]).includes(value)\n );\n}\n\n/** Returns true if `value` is one of the MVP {@link StepStatus} literals. */\nexport function isStepStatus(value: unknown): value is StepStatus {\n return (\n typeof value === \"string\" &&\n (STEP_STATUSES as readonly string[]).includes(value)\n );\n}\n\n/**\n * Narrowing guard for a {@link TraceEvent} object with required MVP fields.\n * Does not deeply validate optional `metadata` shapes.\n */\nexport function isTraceEvent(value: unknown): value is TraceEvent {\n if (!isRecord(value)) return false;\n if (value.schemaVersion !== \"0.1\") return false;\n if (typeof value.timestamp !== \"number\") return false;\n if (typeof value.event !== \"string\") return false;\n\n switch (value.event) {\n case \"run_started\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.name === \"string\" &&\n typeof value.startTime === \"number\"\n );\n }\n case \"run_completed\": {\n return (\n typeof value.runId === \"string\" &&\n (value.status === \"success\" || value.status === \"error\") &&\n typeof value.endTime === \"number\" &&\n typeof value.durationMs === \"number\"\n );\n }\n case \"step_started\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.stepId === \"string\" &&\n typeof value.name === \"string\" &&\n isStepType(value.type) &&\n typeof value.startTime === \"number\"\n );\n }\n case \"step_completed\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.stepId === \"string\" &&\n (value.status === \"success\" || value.status === \"error\") &&\n typeof value.endTime === \"number\" &&\n typeof value.durationMs === \"number\"\n );\n }\n default:\n return false;\n }\n}\n","/**\n * v0.2 shared duration utilities.\n *\n * `parseDuration` is used for filters such as \"since\" / \"older-than\".\n * `formatDuration` is used for compact display in CLI and summaries.\n */\n\nexport function parseDuration(duration: string): number {\n const raw = typeof duration === \"string\" ? duration.trim() : \"\";\n const match = raw.match(/^(\\d+)(ms|[smhd])$/);\n if (!match) {\n throw new Error(\n `Invalid duration format: ${duration}. Use a positive integer followed by ms, s, m, h, or d (e.g. 500ms, 30s, 5m, 2h, 7d).`,\n );\n }\n\n const amount = Number.parseInt(match[1], 10);\n const unit = match[2];\n\n if (!Number.isFinite(amount) || amount <= 0) {\n throw new Error(\n `Invalid duration amount: ${duration}. Amount must be a positive integer.`,\n );\n }\n\n switch (unit) {\n case \"ms\":\n return amount;\n case \"s\":\n return amount * 1000;\n case \"m\":\n return amount * 60 * 1000;\n case \"h\":\n return amount * 60 * 60 * 1000;\n case \"d\":\n return amount * 24 * 60 * 60 * 1000;\n default: {\n // Should be unreachable due to regex.\n throw new Error(`Unknown duration unit: ${unit}`);\n }\n }\n}\n\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms)) {\n return \"0ms\";\n }\n if (ms < 0) {\n throw new Error(`formatDuration: ms must be non-negative (got ${ms})`);\n }\n if (ms < 1000) {\n return `${Math.floor(ms)}ms`;\n }\n if (ms < 60_000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n if (ms < 3_600_000) {\n return `${(ms / 60_000).toFixed(1)}m`;\n }\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\n","import { mkdir } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nimport { nanoid } from \"nanoid\";\n\nimport type { ErrorInfo } from \"./types.js\";\nimport { formatDuration as formatDurationV2 } from \"./utils/duration.js\";\n\n/** Default folder under the user home for AgentInspect data. */\nexport const DEFAULT_TRACE_DIR_NAME = \".agent-inspect\";\n\n/** Subfolder where JSONL run traces are stored. */\nexport const RUNS_DIR_NAME = \"runs\";\n\n/** Writable trace root when the default home path cannot be used. */\nexport const FALLBACK_TRACE_DIR = path.join(\n os.tmpdir(),\n \"agent-inspect\",\n RUNS_DIR_NAME,\n);\n\n/** Maximum display length for run/step names before truncation. */\nexport const MAX_NAME_LENGTH = 100;\n\n/** Returns `run_` + a 10-character nanoid segment. */\nexport function createRunId(): string {\n return `run_${nanoid(10)}`;\n}\n\n/** Returns `step_` + a 10-character nanoid segment. */\nexport function createStepId(): string {\n return `step_${nanoid(10)}`;\n}\n\n/** Formats a duration for CLI display (v0.2 rules). */\nexport function formatDuration(ms: number): string {\n return formatDurationV2(ms);\n}\n\n/**\n * Formats a Unix timestamp (ms) as local `YYYY-MM-DD HH:mm:ss`.\n * Invalid values yield `\"Invalid date\"` (no throw).\n */\nexport function formatTimestamp(timestamp: number): string {\n if (!Number.isFinite(timestamp)) {\n return \"Invalid date\";\n }\n const d = new Date(timestamp);\n if (Number.isNaN(d.getTime())) {\n return \"Invalid date\";\n }\n const y = d.getFullYear();\n const mo = String(d.getMonth() + 1).padStart(2, \"0\");\n const day = String(d.getDate()).padStart(2, \"0\");\n const h = String(d.getHours()).padStart(2, \"0\");\n const min = String(d.getMinutes()).padStart(2, \"0\");\n const s = String(d.getSeconds()).padStart(2, \"0\");\n return `${y}-${mo}-${day} ${h}:${min}:${s}`;\n}\n\n/**\n * Default directory for trace files: `~/DEFAULT_TRACE_DIR_NAME/RUNS_DIR_NAME`.\n * Falls back to {@link FALLBACK_TRACE_DIR} when home cannot be resolved.\n */\nexport function getDefaultTraceDir(): string {\n const envDir = process.env.AGENT_INSPECT_TRACE_DIR;\n if (typeof envDir === \"string\" && envDir.trim() !== \"\") {\n return envDir.trim();\n }\n try {\n const home = os.homedir();\n if (typeof home !== \"string\" || home.trim() === \"\") {\n return FALLBACK_TRACE_DIR;\n }\n return path.join(home, DEFAULT_TRACE_DIR_NAME, RUNS_DIR_NAME);\n } catch {\n return FALLBACK_TRACE_DIR;\n }\n}\n\n/**\n * Full path to the JSONL trace file for a run.\n * `runId` is passed through `path.basename` to avoid traversal; empty ids become `run_unknown`.\n */\nexport function getTraceFilePath(runId: string, traceDir?: string): string {\n const baseDir = traceDir ?? getDefaultTraceDir();\n let safeId =\n typeof runId === \"string\" && runId.trim() !== \"\" ? runId.trim() : \"run_unknown\";\n safeId = path.basename(safeId);\n if (safeId === \"\" || safeId === \".\" || safeId === \"..\") {\n safeId = \"run_unknown\";\n }\n return path.join(baseDir, `${safeId}.jsonl`);\n}\n\n/**\n * Ensures a trace directory exists (recursive). Tries {@link FALLBACK_TRACE_DIR} on failure.\n * Returns the directory path that callers should prefer: primary, fallback, or original if both mkdir attempts fail.\n * Emits concise `[AgentInspect]` warnings on failure; never throws.\n */\nexport async function ensureTraceDir(traceDir: string): Promise<string> {\n const primary = path.resolve(traceDir);\n try {\n await mkdir(primary, { recursive: true });\n return primary;\n } catch {\n warn(`Failed to create trace directory: ${primary}`);\n const fallback = path.resolve(FALLBACK_TRACE_DIR);\n try {\n await mkdir(fallback, { recursive: true });\n return fallback;\n } catch {\n warn(`Failed to create fallback trace directory: ${fallback}`);\n return primary;\n }\n }\n}\n\n/**\n * Normalizes any thrown/caught value into {@link ErrorInfo}.\n * Never throws (circular structures and non-JSON values fall back to a generic message).\n */\nexport function formatError(error: unknown): ErrorInfo {\n if (error instanceof Error) {\n const out: ErrorInfo = { message: error.message };\n if (typeof error.stack === \"string\" && error.stack.length > 0) {\n out.stack = error.stack;\n }\n return out;\n }\n if (typeof error === \"string\") {\n return { message: error };\n }\n if (error === null) {\n return { message: \"Unknown error: null\" };\n }\n if (error === undefined) {\n return { message: \"Unknown error: undefined\" };\n }\n if (\n typeof error === \"number\" ||\n typeof error === \"boolean\" ||\n typeof error === \"bigint\"\n ) {\n return { message: String(error) };\n }\n if (typeof error === \"object\") {\n try {\n return { message: JSON.stringify(error) };\n } catch {\n return { message: \"Unknown error\" };\n }\n }\n return { message: \"Unknown error\" };\n}\n\n/**\n * Truncates a display name to `maxLength`, appending `\"...\"` when shortened.\n * Empty or non-string input becomes `\"unnamed\"`.\n */\nexport function truncateName(name: string, maxLength = MAX_NAME_LENGTH): string {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n return \"unnamed\";\n }\n const trimmed = name.trim();\n if (trimmed.length <= maxLength) {\n return trimmed;\n }\n const ellipsis = \"...\";\n const head = Math.max(0, maxLength - ellipsis.length);\n return `${trimmed.slice(0, head)}${ellipsis}`;\n}\n\n/**\n * Instrumentation-only warning to stderr. Not a general-purpose logger.\n * Optional `error` is summarized via {@link formatError} (message only).\n */\nexport function warn(message: string, error?: unknown): void {\n const base = `[AgentInspect] ${message}`;\n if (error === undefined) {\n console.warn(base);\n return;\n }\n console.warn(`${base}: ${formatError(error).message}`);\n}\n","import { appendFile, readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { TraceEvent } from \"./types.js\";\nimport { isStepType } from \"./types.js\";\nimport {\n DEFAULT_MAX_EVENT_BYTES,\n prepareTraceEventForDisk,\n resolveTraceSafetyOptions,\n} from \"./trace-event-safety.js\";\nimport { parseTraceJsonl } from \"./read-trace.js\";\nimport {\n ensureTraceDir,\n FALLBACK_TRACE_DIR,\n getTraceFilePath,\n warn,\n} from \"./utils.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction nonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim() !== \"\";\n}\n\nfunction finiteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction optionalErrorInfo(value: unknown): boolean {\n if (value === undefined) return true;\n if (!isRecord(value)) return false;\n if (typeof value.message !== \"string\") return false;\n if (\"stack\" in value && value.stack !== undefined) {\n if (typeof value.stack !== \"string\") return false;\n }\n return true;\n}\n\n/**\n * Strict MVP validation before writing JSONL. Rejects empty ids, non-finite times, and malformed payloads.\n */\nexport function validateEvent(event: unknown): event is TraceEvent {\n if (!isRecord(event)) return false;\n if (event.schemaVersion !== \"0.1\") return false;\n if (!finiteNumber(event.timestamp)) return false;\n if (typeof event.event !== \"string\") return false;\n\n switch (event.event) {\n case \"run_started\": {\n if (\n !nonEmptyString(event.runId) ||\n !nonEmptyString(event.name) ||\n !finiteNumber(event.startTime)\n ) {\n return false;\n }\n if (event.metadata !== undefined && !isRecord(event.metadata)) {\n return false;\n }\n return true;\n }\n case \"run_completed\": {\n return (\n nonEmptyString(event.runId) &&\n (event.status === \"success\" || event.status === \"error\") &&\n finiteNumber(event.endTime) &&\n finiteNumber(event.durationMs) &&\n optionalErrorInfo(event.error)\n );\n }\n case \"step_started\": {\n if (\n !nonEmptyString(event.runId) ||\n !nonEmptyString(event.stepId) ||\n !nonEmptyString(event.name) ||\n !isStepType(event.type) ||\n !finiteNumber(event.startTime)\n ) {\n return false;\n }\n if (event.parentId !== undefined && typeof event.parentId !== \"string\") {\n return false;\n }\n if (event.metadata !== undefined && !isRecord(event.metadata)) {\n return false;\n }\n return true;\n }\n case \"step_completed\": {\n return (\n nonEmptyString(event.runId) &&\n nonEmptyString(event.stepId) &&\n (event.status === \"success\" || event.status === \"error\") &&\n finiteNumber(event.endTime) &&\n finiteNumber(event.durationMs) &&\n optionalErrorInfo(event.error)\n );\n }\n default:\n return false;\n }\n}\n\n/** Serializes a trace line as compact JSON without a trailing newline. */\nexport function serializeEvent(event: TraceEvent): string {\n try {\n return JSON.stringify(event);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Creates (or truncates) an empty JSONL file for a run. Uses {@link ensureTraceDir} then {@link getTraceFilePath}.\n * On failure, retries once under {@link FALLBACK_TRACE_DIR}.\n */\nexport async function initializeTraceFile(\n runId: string,\n traceDir: string,\n): Promise<string | undefined> {\n try {\n const usable = await ensureTraceDir(traceDir);\n const filePath = getTraceFilePath(runId, usable);\n await writeFile(filePath, \"\", \"utf-8\");\n return filePath;\n } catch (e) {\n warn(\"Failed to initialize trace file\", e);\n }\n\n try {\n const usable = await ensureTraceDir(FALLBACK_TRACE_DIR);\n const filePath = getTraceFilePath(runId, usable);\n await writeFile(filePath, \"\", \"utf-8\");\n return filePath;\n } catch (e) {\n warn(\"Failed to initialize trace file on fallback directory\", e);\n return undefined;\n }\n}\n\n/**\n * Appends one validated JSONL line for `event.runId`. Falls back to {@link FALLBACK_TRACE_DIR} on append failure.\n */\nfunction ensureEventWithinBounds(event: TraceEvent): TraceEvent {\n const line = serializeEvent(event);\n if (line === \"\") return event;\n const bytes = Buffer.byteLength(line, \"utf8\");\n if (bytes <= DEFAULT_MAX_EVENT_BYTES) return event;\n return prepareTraceEventForDisk(event, resolveTraceSafetyOptions());\n}\n\nexport async function writeTraceEvent(\n event: TraceEvent,\n traceDir: string,\n): Promise<void> {\n const bounded = ensureEventWithinBounds(event);\n\n if (!validateEvent(bounded)) {\n warn(\"Skipped invalid trace event (validation failed)\");\n return;\n }\n\n const line = serializeEvent(bounded);\n if (line === \"\") {\n warn(\"Skipped trace event (serialization failed)\");\n return;\n }\n\n const payload = `${line}\\n`;\n\n const tryAppend = async (dir: string): Promise<boolean> => {\n try {\n const usable = await ensureTraceDir(dir);\n const filePath = getTraceFilePath(event.runId, usable);\n await appendFile(filePath, payload, \"utf-8\");\n return true;\n } catch {\n return false;\n }\n };\n\n if (await tryAppend(traceDir)) {\n return;\n }\n\n warn(`Failed to append trace event for run ${event.runId}`);\n\n if (await tryAppend(FALLBACK_TRACE_DIR)) {\n return;\n }\n\n warn(\"Failed to append trace event to fallback directory\");\n}\n\n/**\n * Reads raw JSONL file contents for a run, or `undefined` if missing or unreadable.\n */\nexport async function readTraceFile(\n runId: string,\n traceDir: string,\n): Promise<string | undefined> {\n try {\n const filePath = getTraceFilePath(runId, traceDir);\n return await readFile(filePath, \"utf-8\");\n } catch (e) {\n if (e && typeof e === \"object\" && \"code\" in e && e.code === \"ENOENT\") {\n return undefined;\n }\n warn(\"Unexpected error reading trace file\", e);\n return undefined;\n }\n}\n\n/**\n * Parses JSONL into validated {@link TraceEvent} rows (v0.1 native or v0.2 normalized).\n * Invalid lines are skipped with a warning.\n */\nexport async function readTraceEvents(\n runId: string,\n traceDir: string,\n): Promise<TraceEvent[]> {\n try {\n const filePath = getTraceFilePath(runId, traceDir);\n return await readTraceEventsFromFile(filePath);\n } catch (e) {\n warn(\"Failed to read trace events\", e);\n return [];\n }\n}\n\n/**\n * Reads and normalizes trace events from an exact file path.\n * Used by directory scans where the embedded run id may differ from the basename.\n */\nexport async function readTraceEventsFromFile(\n filePath: string,\n): Promise<TraceEvent[]> {\n try {\n const raw = await readFile(filePath, \"utf-8\");\n return parseTraceJsonl(raw, { validate: validateEvent }).events;\n } catch (e) {\n if (e && typeof e === \"object\" && \"code\" in e && e.code === \"ENOENT\") {\n return [];\n }\n warn(\"Failed to read trace events from file\", e);\n return [];\n }\n}\n\n/**\n * Lists `.jsonl` file names in `traceDir`, newest by mtime first (name sort as tie-breaker).\n */\nexport async function listTraceFiles(traceDir: string): Promise<string[]> {\n try {\n const usable = path.resolve(traceDir);\n const names = await readdir(usable);\n const jsonl = names.filter((n) => n.endsWith(\".jsonl\"));\n const withStat = await Promise.all(\n jsonl.map(async (name) => {\n try {\n const st = await stat(path.join(usable, name));\n return { name, mtime: st.mtimeMs };\n } catch {\n return { name, mtime: 0 };\n }\n }),\n );\n withStat.sort((a, b) => {\n if (b.mtime !== a.mtime) return b.mtime - a.mtime;\n return a.name.localeCompare(b.name);\n });\n return withStat.map((x) => x.name);\n } catch {\n return [];\n }\n}\n\n/** Maps a `.jsonl` file name to its run id (basename only; no traversal). */\nexport function getRunIdFromTraceFileName(fileName: string): string | undefined {\n try {\n const base = path.basename(fileName);\n if (!base.endsWith(\".jsonl\")) return undefined;\n const id = base.slice(0, -\".jsonl\".length);\n return id === \"\" ? undefined : id;\n } catch {\n return undefined;\n }\n}\n","import { Redactor } from \"./logs/redactor.js\";\nimport {\n applyProfileMetadataCaps,\n resolveRedactionProfile,\n type ResolvedRedactionProfile,\n} from \"./redaction-profiles.js\";\nimport { serializeEvent } from \"./storage.js\";\nimport type { RedactionRule } from \"./types/log-config.js\";\nimport {\n isPersistedInspectEvent,\n type PersistedInspectError,\n type PersistedInspectEvent,\n type PersistedTokenUsage,\n type PersistedTraceContext,\n} from \"./types/persisted-inspect-event.js\";\nimport type {\n InspectRunOptions,\n RedactionProfile,\n StepMetadata,\n TraceEvent,\n} from \"./types.js\";\n\n/** Default max length for string metadata values (non-preview keys). */\nexport const DEFAULT_MAX_METADATA_VALUE_LENGTH = 2000;\n\n/** Default max length for preview-like metadata keys (contains `preview`, case-insensitive). */\nexport const DEFAULT_MAX_PREVIEW_LENGTH = 500;\n\n/** Default max serialized JSONL line size in bytes (UTF-8). */\nexport const DEFAULT_MAX_EVENT_BYTES = 65_536;\n\n/** Resolved trace safety settings used at write time. */\nexport interface TraceSafetyOptions {\n redactEnabled: boolean;\n redactionRules?: RedactionRule[];\n redactionProfile: RedactionProfile;\n profileExtraKeys: readonly string[];\n maxMetadataValueLength: number;\n maxPreviewLength: number;\n maxEventBytes: number;\n}\n\nexport type { ResolvedRedactionProfile };\nexport { resolveRedactionProfile };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nconst KNOWN_PERSISTED_EVENT_FIELDS = new Set([\n \"schemaVersion\",\n \"eventId\",\n \"runId\",\n \"kind\",\n \"name\",\n \"parentId\",\n \"status\",\n \"timestamp\",\n \"startedAt\",\n \"endedAt\",\n \"durationMs\",\n \"confidence\",\n \"source\",\n \"attributes\",\n \"inputSummary\",\n \"outputSummary\",\n \"error\",\n \"tokenUsage\",\n \"trace\",\n]);\n\nfunction isSafeExtensionFieldName(key: string): boolean {\n return key !== \"__proto__\" && key !== \"constructor\" && key !== \"prototype\";\n}\n\nfunction isPreviewKey(key: string): boolean {\n return key.toLowerCase().includes(\"preview\");\n}\n\nfunction truncateString(value: string, maxLen: number): string {\n if (maxLen <= 0) return \"…\";\n if (value.length <= maxLen) return value;\n return `${value.slice(0, maxLen)}…`;\n}\n\nfunction byteLength(text: string): number {\n return Buffer.byteLength(text, \"utf8\");\n}\n\n/** Resolves {@link InspectRunOptions} trace safety fields with safe defaults. */\nexport function resolveTraceSafetyOptions(\n options?: Pick<\n InspectRunOptions,\n | \"redact\"\n | \"redactionProfile\"\n | \"maxEventBytes\"\n | \"maxMetadataValueLength\"\n | \"maxPreviewLength\"\n >,\n): TraceSafetyOptions {\n const redact = options?.redact;\n let redactEnabled = true;\n let redactionRules: RedactionRule[] | undefined;\n\n if (redact === false) {\n redactEnabled = false;\n } else if (redact === true || redact === undefined) {\n redactEnabled = true;\n } else if (isRecord(redact)) {\n redactEnabled = true;\n redactionRules = redact.rules;\n }\n\n const profile = options?.redactionProfile ?? \"local\";\n const resolvedProfile = resolveRedactionProfile(profile);\n\n const userMaxMetadata =\n typeof options?.maxMetadataValueLength === \"number\" &&\n Number.isFinite(options.maxMetadataValueLength) &&\n options.maxMetadataValueLength >= 0\n ? Math.floor(options.maxMetadataValueLength)\n : undefined;\n const userMaxPreview =\n typeof options?.maxPreviewLength === \"number\" &&\n Number.isFinite(options.maxPreviewLength) &&\n options.maxPreviewLength >= 0\n ? Math.floor(options.maxPreviewLength)\n : undefined;\n\n let maxMetadataValueLength = userMaxMetadata ?? DEFAULT_MAX_METADATA_VALUE_LENGTH;\n let maxPreviewLength = userMaxPreview ?? DEFAULT_MAX_PREVIEW_LENGTH;\n\n if (redactEnabled && profile !== \"local\") {\n const capped = applyProfileMetadataCaps(\n maxMetadataValueLength,\n maxPreviewLength,\n resolvedProfile,\n );\n maxMetadataValueLength = capped.maxMetadataValueLength;\n maxPreviewLength = capped.maxPreviewLength;\n }\n\n return {\n redactEnabled,\n redactionRules,\n redactionProfile: profile,\n profileExtraKeys: redactEnabled ? resolvedProfile.extraKeys : [],\n maxMetadataValueLength,\n maxPreviewLength,\n maxEventBytes:\n typeof options?.maxEventBytes === \"number\" &&\n Number.isFinite(options.maxEventBytes) &&\n options.maxEventBytes > 0\n ? Math.floor(options.maxEventBytes)\n : DEFAULT_MAX_EVENT_BYTES,\n };\n}\n\nfunction boundMetadataValue(\n key: string,\n value: unknown,\n opts: TraceSafetyOptions,\n seen: WeakSet<object>,\n depth: number,\n): unknown {\n if (depth > 32) return \"[MaxDepth]\";\n\n if (typeof value === \"bigint\") {\n return `${value.toString()}n`;\n }\n if (typeof value === \"function\") {\n return \"[Function]\";\n }\n if (typeof value === \"symbol\") {\n return \"[Symbol]\";\n }\n if (typeof value === \"number\" && !Number.isFinite(value)) {\n return String(value);\n }\n if (value === undefined) {\n return null;\n }\n\n if (value === null || typeof value !== \"object\") {\n if (typeof value === \"string\") {\n const max = isPreviewKey(key) ? opts.maxPreviewLength : opts.maxMetadataValueLength;\n return truncateString(value, max);\n }\n return value;\n }\n\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n\n if (Array.isArray(value)) {\n const maxItems = 50;\n const out = value\n .slice(0, maxItems)\n .map((item, index) =>\n boundMetadataValue(String(index), item, opts, seen, depth + 1),\n );\n if (value.length > maxItems) {\n out.push(`…(+${value.length - maxItems} more)`);\n }\n return out;\n }\n\n const record = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n try {\n for (const [k, v] of Object.entries(record)) {\n out[k] = boundMetadataValue(k, v, opts, seen, depth + 1);\n }\n } catch {\n return { truncated: true, reason: \"metadataEnumerationFailed\" };\n }\n return out;\n}\n\nfunction redactMetadata(\n metadata: Record<string, unknown>,\n opts: TraceSafetyOptions,\n): Record<string, unknown> {\n if (!opts.redactEnabled) return { ...metadata };\n const redactor = new Redactor({\n rules: opts.redactionRules,\n extraKeys: opts.profileExtraKeys,\n });\n return redactor.redactRecord(metadata);\n}\n\n/** Redacts (when enabled) and truncates metadata values for disk persistence. */\nexport function prepareMetadataForDisk(\n metadata: Record<string, unknown> | StepMetadata,\n opts: TraceSafetyOptions,\n): Record<string, unknown> {\n try {\n const preBounded = boundMetadataValue(\n \"metadata\",\n metadata,\n opts,\n new WeakSet<object>(),\n 0,\n );\n const redacted = redactMetadata(\n isRecord(preBounded) ? preBounded : {},\n opts,\n );\n const bounded = boundMetadataValue(\n \"metadata\",\n redacted,\n opts,\n new WeakSet<object>(),\n 0,\n );\n return isRecord(bounded) ? bounded : {};\n } catch {\n return { truncated: true, reason: \"metadataPreparationFailed\" };\n }\n}\n\nfunction truncateErrorStack(\n event: TraceEvent,\n maxLen: number,\n): TraceEvent {\n if (event.event !== \"run_completed\" && event.event !== \"step_completed\") {\n return event;\n }\n if (!event.error?.stack || typeof event.error.stack !== \"string\") {\n return event;\n }\n return {\n ...event,\n error: {\n ...event.error,\n stack: truncateString(event.error.stack, maxLen),\n },\n };\n}\n\nfunction replaceMetadataWithTruncationMarker(\n event: TraceEvent,\n originalApproxBytes: number,\n): TraceEvent {\n const marker = {\n truncated: true,\n reason: \"maxEventBytes\",\n originalApproxBytes,\n };\n if (event.event === \"run_started\") {\n return { ...event, metadata: marker };\n }\n if (event.event === \"step_started\") {\n return { ...event, metadata: marker };\n }\n return event;\n}\n\nfunction shrinkMetadataLimits(\n opts: TraceSafetyOptions,\n factor: number,\n): TraceSafetyOptions {\n return {\n ...opts,\n maxMetadataValueLength: Math.max(32, Math.floor(opts.maxMetadataValueLength * factor)),\n maxPreviewLength: Math.max(16, Math.floor(opts.maxPreviewLength * factor)),\n };\n}\n\nfunction applyMetadataToEvent(\n event: TraceEvent,\n metadata: Record<string, unknown>,\n): TraceEvent {\n if (event.event === \"run_started\") {\n return { ...event, metadata };\n }\n if (event.event === \"step_started\") {\n return { ...event, metadata: metadata as StepMetadata };\n }\n return event;\n}\n\nfunction eventHasMetadata(event: TraceEvent): boolean {\n return (\n (event.event === \"run_started\" || event.event === \"step_started\") &&\n event.metadata !== undefined\n );\n}\n\nfunction getEventMetadata(event: TraceEvent): Record<string, unknown> | undefined {\n if (event.event === \"run_started\" || event.event === \"step_started\") {\n return event.metadata as Record<string, unknown> | undefined;\n }\n return undefined;\n}\n\n/**\n * Applies redaction, metadata truncation, and final serialized size bounds.\n * Never throws; returns a schema-valid event or a minimally truncated variant.\n */\nexport function prepareTraceEventForDisk(\n event: TraceEvent,\n opts: TraceSafetyOptions,\n): TraceEvent {\n try {\n let working: TraceEvent = { ...event };\n\n const rawMetadata = getEventMetadata(working);\n if (rawMetadata !== undefined) {\n const safe = prepareMetadataForDisk(rawMetadata, opts);\n working = applyMetadataToEvent(working, safe);\n }\n\n let serialized = serializeEvent(working);\n if (serialized === \"\") {\n return working;\n }\n\n let bytes = byteLength(serialized);\n if (bytes <= opts.maxEventBytes) {\n return working;\n }\n\n if (rawMetadata !== undefined) {\n for (const factor of [0.5, 0.25, 0.1]) {\n const tighter = shrinkMetadataLimits(opts, factor);\n const shrunk = prepareMetadataForDisk(rawMetadata, tighter);\n working = applyMetadataToEvent(working, shrunk);\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n }\n\n working = replaceMetadataWithTruncationMarker(working, bytes);\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n }\n\n working = truncateErrorStack(working, Math.min(opts.maxMetadataValueLength, 500));\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n\n if (eventHasMetadata(working)) {\n working = replaceMetadataWithTruncationMarker(working, bytes);\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n\n if (working.event === \"run_started\") {\n const { metadata: _meta, ...rest } = working;\n working = rest;\n } else if (working.event === \"step_started\") {\n const { metadata: _meta, ...rest } = working;\n working = rest;\n }\n }\n\n return working;\n } catch {\n if (event.event === \"run_started\" || event.event === \"step_started\") {\n return applyMetadataToEvent(event, {\n truncated: true,\n reason: \"prepareTraceEventFailed\",\n });\n }\n return event;\n }\n}\n\nfunction safeGet(record: Record<string, unknown>, key: string): unknown {\n try {\n return record[key];\n } catch {\n return undefined;\n }\n}\n\nfunction optionalBoundedString(\n value: unknown,\n _key: string,\n opts: TraceSafetyOptions,\n): string | undefined {\n if (typeof value !== \"string\") return undefined;\n return truncateString(value, opts.maxMetadataValueLength);\n}\n\nfunction requiredBoundedString(\n value: unknown,\n key: string,\n opts: TraceSafetyOptions,\n): string | undefined {\n const out = optionalBoundedString(value, key, opts);\n return out && out.length > 0 ? out : undefined;\n}\n\nfunction preparePersistedSummaryForDisk(\n key: \"input\" | \"output\",\n value: unknown,\n opts: TraceSafetyOptions,\n): unknown {\n try {\n const redactor = new Redactor({\n rules: opts.redactionRules,\n extraKeys: opts.profileExtraKeys,\n });\n const redacted = opts.redactEnabled ? redactor.redactValue(key, value) : value;\n return boundMetadataValue(key, redacted, opts, new WeakSet<object>(), 0);\n } catch {\n return { truncated: true, reason: \"summaryPreparationFailed\" };\n }\n}\n\nfunction preparePersistedErrorForDisk(\n value: unknown,\n opts: TraceSafetyOptions,\n): PersistedInspectError | undefined {\n if (!isRecord(value)) return undefined;\n\n try {\n const redactor = new Redactor({\n rules: opts.redactionRules,\n extraKeys: opts.profileExtraKeys,\n });\n const rawMessage = safeGet(value, \"message\");\n const redactedMessage = opts.redactEnabled\n ? redactor.redactValue(\"message\", rawMessage)\n : rawMessage;\n const boundedMessage = boundMetadataValue(\n \"message\",\n redactedMessage,\n opts,\n new WeakSet<object>(),\n 0,\n );\n const message =\n typeof boundedMessage === \"string\" && boundedMessage.length > 0\n ? boundedMessage\n : \"Unknown error\";\n\n const out: PersistedInspectError = { message };\n const name = optionalBoundedString(safeGet(value, \"name\"), \"name\", opts);\n const code = optionalBoundedString(safeGet(value, \"code\"), \"code\", opts);\n if (name !== undefined) out.name = name;\n if (code !== undefined) out.code = code;\n return out;\n } catch {\n return { message: \"Error preparation failed\" };\n }\n}\n\nfunction prepareTokenUsage(value: unknown): PersistedTokenUsage | undefined {\n if (!isRecord(value)) return undefined;\n const out: PersistedTokenUsage = {};\n for (const key of [\"input\", \"output\", \"total\", \"cached\"] as const) {\n const item = safeGet(value, key);\n if (typeof item === \"number\" && Number.isFinite(item) && item >= 0) {\n out[key] = item;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction prepareTraceContext(\n value: unknown,\n opts: TraceSafetyOptions,\n): PersistedTraceContext | undefined {\n if (!isRecord(value)) return undefined;\n const out: PersistedTraceContext = {};\n const traceId = optionalBoundedString(safeGet(value, \"traceId\"), \"traceId\", opts);\n const spanId = optionalBoundedString(safeGet(value, \"spanId\"), \"spanId\", opts);\n const parentSpanId = optionalBoundedString(\n safeGet(value, \"parentSpanId\"),\n \"parentSpanId\",\n opts,\n );\n if (traceId !== undefined) out.traceId = traceId;\n if (spanId !== undefined) out.spanId = spanId;\n if (parentSpanId !== undefined) out.parentSpanId = parentSpanId;\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction preparePersistedExtensionFieldForDisk(\n key: string,\n value: unknown,\n opts: TraceSafetyOptions,\n): unknown {\n if (isRecord(value)) {\n return prepareMetadataForDisk(value, opts);\n }\n\n const prepared = prepareMetadataForDisk({ [key]: value }, opts);\n return Object.prototype.hasOwnProperty.call(prepared, key)\n ? prepared[key]\n : undefined;\n}\n\nfunction preserveV10ExtensionFields(\n source: Record<string, unknown>,\n candidate: PersistedInspectEvent,\n opts: TraceSafetyOptions,\n): void {\n if (candidate.schemaVersion !== \"1.0\") return;\n\n for (const [key, value] of Object.entries(source)) {\n if (\n KNOWN_PERSISTED_EVENT_FIELDS.has(key) ||\n !isSafeExtensionFieldName(key)\n ) {\n continue;\n }\n\n const prepared = preparePersistedExtensionFieldForDisk(key, value, opts);\n if (prepared !== undefined) {\n candidate[key] = prepared;\n }\n }\n}\n\nfunction serializedPersistedEvent(event: PersistedInspectEvent): string | undefined {\n try {\n return JSON.stringify(event);\n } catch {\n return undefined;\n }\n}\n\nfunction persistedEventByteLength(event: PersistedInspectEvent): number | undefined {\n const serialized = serializedPersistedEvent(event);\n return serialized === undefined ? undefined : byteLength(serialized);\n}\n\nfunction minimalPersistedEvent(\n event: PersistedInspectEvent,\n opts: TraceSafetyOptions,\n originalApproxBytes: number,\n): PersistedInspectEvent {\n return {\n schemaVersion: event.schemaVersion,\n eventId: truncateString(event.eventId, 128),\n runId: truncateString(event.runId, 128),\n kind: event.kind,\n name: truncateString(event.name, 128),\n ...(event.status !== undefined ? { status: event.status } : {}),\n timestamp: truncateString(event.timestamp, 128),\n confidence: event.confidence,\n source: {\n type: event.source.type,\n ...(event.source.name !== undefined\n ? { name: truncateString(event.source.name, 128) }\n : {}),\n ...(event.source.version !== undefined\n ? { version: truncateString(event.source.version, 128) }\n : {}),\n },\n attributes: {\n truncated: true,\n reason: \"maxEventBytes\",\n originalApproxBytes,\n maxEventBytes: opts.maxEventBytes,\n },\n };\n}\n\nfunction tinyPersistedEvent(event: PersistedInspectEvent): PersistedInspectEvent {\n return {\n schemaVersion: event.schemaVersion,\n eventId: truncateString(event.eventId, 32),\n runId: truncateString(event.runId, 32),\n kind: event.kind,\n name: truncateString(event.name, 32),\n timestamp: truncateString(event.timestamp, 32),\n confidence: event.confidence,\n source: { type: event.source.type },\n attributes: { truncated: true, reason: \"maxEventBytes\" },\n };\n}\n\nfunction enforcePersistedEventSize(\n event: PersistedInspectEvent,\n opts: TraceSafetyOptions,\n): PersistedInspectEvent | undefined {\n const bytes = persistedEventByteLength(event);\n if (bytes === undefined) return undefined;\n if (bytes <= opts.maxEventBytes) return event;\n\n const minimal = minimalPersistedEvent(event, opts, bytes);\n const minimalBytes = persistedEventByteLength(minimal);\n if (minimalBytes !== undefined && minimalBytes <= opts.maxEventBytes) {\n return minimal;\n }\n\n const tiny = tinyPersistedEvent(event);\n return isPersistedInspectEvent(tiny) ? tiny : undefined;\n}\n\n/**\n * Prepares persisted inspect events for built-in persistence.\n *\n * The helper is intentionally non-throwing: invalid required fields return\n * `undefined`; supported optional fields are redacted, bounded, JSON-safe, and\n * final serialized-size checked before a writer sees the event.\n */\nexport function preparePersistedInspectEventForWrite(\n value: unknown,\n opts: TraceSafetyOptions = resolveTraceSafetyOptions(),\n): PersistedInspectEvent | undefined {\n try {\n if (!isRecord(value)) return undefined;\n\n const source = safeGet(value, \"source\");\n if (!isRecord(source)) return undefined;\n\n const candidate: PersistedInspectEvent = {\n schemaVersion: safeGet(value, \"schemaVersion\") as PersistedInspectEvent[\"schemaVersion\"],\n eventId: requiredBoundedString(safeGet(value, \"eventId\"), \"eventId\", opts) ?? \"\",\n runId: requiredBoundedString(safeGet(value, \"runId\"), \"runId\", opts) ?? \"\",\n kind: safeGet(value, \"kind\") as PersistedInspectEvent[\"kind\"],\n name: requiredBoundedString(safeGet(value, \"name\"), \"name\", opts) ?? \"\",\n timestamp: requiredBoundedString(safeGet(value, \"timestamp\"), \"timestamp\", opts) ?? \"\",\n confidence: safeGet(value, \"confidence\") as PersistedInspectEvent[\"confidence\"],\n source: {\n type: safeGet(source, \"type\") as PersistedInspectEvent[\"source\"][\"type\"],\n },\n };\n\n const parentId = requiredBoundedString(safeGet(value, \"parentId\"), \"parentId\", opts);\n const status = safeGet(value, \"status\");\n const startedAt = optionalBoundedString(safeGet(value, \"startedAt\"), \"startedAt\", opts);\n const endedAt = optionalBoundedString(safeGet(value, \"endedAt\"), \"endedAt\", opts);\n const durationMs = safeGet(value, \"durationMs\");\n const sourceName = optionalBoundedString(safeGet(source, \"name\"), \"name\", opts);\n const sourceVersion = optionalBoundedString(safeGet(source, \"version\"), \"version\", opts);\n\n if (parentId !== undefined) candidate.parentId = parentId;\n if (\n status === \"running\" ||\n status === \"ok\" ||\n status === \"error\" ||\n status === \"unknown\"\n ) {\n candidate.status = status;\n }\n if (startedAt !== undefined) candidate.startedAt = startedAt;\n if (endedAt !== undefined) candidate.endedAt = endedAt;\n if (\n typeof durationMs === \"number\" &&\n Number.isFinite(durationMs) &&\n durationMs >= 0\n ) {\n candidate.durationMs = durationMs;\n }\n if (sourceName !== undefined) candidate.source.name = sourceName;\n if (sourceVersion !== undefined) candidate.source.version = sourceVersion;\n\n const attributes = safeGet(value, \"attributes\");\n if (isRecord(attributes)) {\n candidate.attributes = prepareMetadataForDisk(attributes, opts);\n }\n\n if (safeGet(value, \"inputSummary\") !== undefined) {\n candidate.inputSummary = preparePersistedSummaryForDisk(\n \"input\",\n safeGet(value, \"inputSummary\"),\n opts,\n );\n }\n if (safeGet(value, \"outputSummary\") !== undefined) {\n candidate.outputSummary = preparePersistedSummaryForDisk(\n \"output\",\n safeGet(value, \"outputSummary\"),\n opts,\n );\n }\n\n const error = preparePersistedErrorForDisk(safeGet(value, \"error\"), opts);\n if (error !== undefined) candidate.error = error;\n\n const tokenUsage = prepareTokenUsage(safeGet(value, \"tokenUsage\"));\n if (tokenUsage !== undefined) candidate.tokenUsage = tokenUsage;\n\n const trace = prepareTraceContext(safeGet(value, \"trace\"), opts);\n if (trace !== undefined) candidate.trace = trace;\n\n preserveV10ExtensionFields(value, candidate, opts);\n\n if (!isPersistedInspectEvent(candidate)) return undefined;\n return enforcePersistedEventSize(candidate, opts);\n } catch {\n return undefined;\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport { extractCorrelationMetadata } from \"./correlation-metadata.js\";\nimport type { ExecutionContext, TraceCorrelationMetadata } from \"./types.js\";\nimport {\n resolveTraceSafetyOptions,\n type TraceSafetyOptions,\n} from \"./trace-event-safety.js\";\n\ntype RuntimeExecutionContext = ExecutionContext & {\n currentStepId?: string;\n currentDepth: number;\n traceSafety: TraceSafetyOptions;\n};\n\nconst storage = new AsyncLocalStorage<RuntimeExecutionContext>();\n\nfunction toPublicContext(ctx: RuntimeExecutionContext): ExecutionContext {\n return {\n runId: ctx.runId,\n runName: ctx.runName,\n traceDir: ctx.traceDir,\n silent: ctx.silent,\n metadata: ctx.metadata,\n };\n}\n\nfunction invoke<T>(fn: () => T | Promise<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n try {\n Promise.resolve(fn()).then(resolve, reject);\n } catch (e) {\n reject(e);\n }\n });\n}\n\n/** Returns the active run context, without internal step fields. */\nexport function getCurrentContext(): ExecutionContext | undefined {\n try {\n const s = storage.getStore();\n if (!s) return undefined;\n return toPublicContext(s);\n } catch {\n return undefined;\n }\n}\n\n/** Active `runId` when inside `runWithContext`, else `undefined`. */\nexport function getCurrentRunId(): string | undefined {\n try {\n return storage.getStore()?.runId;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Correlation metadata for the active run (`correlationId`, `requestId`, `decisionId`, `groupId`).\n * `undefined` outside `inspectRun` / `maybeInspectRun` or when no correlation fields were set.\n */\nexport function getCurrentCorrelationMetadata():\n | TraceCorrelationMetadata\n | undefined {\n try {\n return extractCorrelationMetadata(storage.getStore()?.metadata);\n } catch {\n return undefined;\n }\n}\n\n/** Active `runName` when inside `runWithContext`, else `undefined`. */\nexport function getCurrentRunName(): string | undefined {\n try {\n return storage.getStore()?.runName;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Active step id in this async scope (parent for nested `step()` calls).\n * `undefined` at run root or outside any run.\n */\nexport function getCurrentStepId(): string | undefined {\n try {\n return storage.getStore()?.currentStepId;\n } catch {\n return undefined;\n }\n}\n\n/** Alias of {@link getCurrentStepId} for readability in step instrumentation. */\nexport function getParentStepId(): string | undefined {\n return getCurrentStepId();\n}\n\n/**\n * Nesting depth: `0` at run root, increments by one per nested `runWithStepContext`.\n * Returns `0` outside any run.\n */\nexport function getCurrentDepth(): number {\n try {\n const d = storage.getStore()?.currentDepth;\n return typeof d === \"number\" && Number.isFinite(d) ? d : 0;\n } catch {\n return 0;\n }\n}\n\nexport function hasActiveContext(): boolean {\n try {\n return storage.getStore() !== undefined;\n } catch {\n return false;\n }\n}\n\nexport function getTraceDirFromContext(): string | undefined {\n try {\n return storage.getStore()?.traceDir;\n } catch {\n return undefined;\n }\n}\n\nexport function isSilentContext(): boolean {\n try {\n const s = storage.getStore();\n return s ? s.silent : false;\n } catch {\n return false;\n }\n}\n\n/** Resolved trace safety settings for the active run (redaction + size bounds). */\nexport function getTraceSafetyFromContext(): TraceSafetyOptions | undefined {\n try {\n return storage.getStore()?.traceSafety;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Runs `fn` with a fresh AgentInspect run context (depth 0, no active step).\n * Propagates sync/async results and rejections; does not swallow user errors.\n */\nexport function runWithContext<T>(\n context: ExecutionContext,\n fn: () => Promise<T> | T,\n traceSafety: TraceSafetyOptions = resolveTraceSafetyOptions(),\n): Promise<T> {\n const runtime: RuntimeExecutionContext = {\n runId: context.runId,\n runName: context.runName,\n traceDir: context.traceDir,\n silent: context.silent,\n metadata: context.metadata,\n traceSafety,\n currentDepth: 0,\n };\n\n return new Promise((resolve, reject) => {\n storage.run(runtime, () => {\n try {\n Promise.resolve(fn()).then(resolve, reject);\n } catch (e) {\n reject(e);\n }\n });\n });\n}\n\n/**\n * Runs `fn` with `stepId` as the active step (incremented depth).\n * If no run is active, runs `fn` without altering async context.\n */\nexport function runWithStepContext<T>(\n stepId: string,\n fn: () => Promise<T> | T,\n): Promise<T> {\n let parent: RuntimeExecutionContext | undefined;\n try {\n parent = storage.getStore();\n } catch {\n parent = undefined;\n }\n\n if (!parent) {\n return invoke(fn);\n }\n\n const derived: RuntimeExecutionContext = {\n runId: parent.runId,\n runName: parent.runName,\n traceDir: parent.traceDir,\n silent: parent.silent,\n metadata: parent.metadata,\n traceSafety: parent.traceSafety,\n currentStepId: stepId,\n currentDepth: parent.currentDepth + 1,\n };\n\n return new Promise((resolve, reject) => {\n storage.run(derived, () => {\n try {\n Promise.resolve(fn()).then(resolve, reject);\n } catch (e) {\n reject(e);\n }\n });\n });\n}\n","import chalk from \"chalk\";\n\nimport { isSilentContext } from \"./context.js\";\nimport type { ErrorInfo, RunStatus, StepStatus } from \"./types.js\";\nimport { formatDuration, truncateName } from \"./utils.js\";\n\n/** Two spaces per nesting level in terminal output. */\nexport const TERMINAL_INDENT = \" \";\n\n/** Max display length for names in terminal output. */\nexport const MAX_TERMINAL_NAME_LENGTH = 80;\n\n/** Max nesting depth used for indentation (prevents huge indents). */\nexport const MAX_TERMINAL_DEPTH = 10;\n\nfunction normalizeDepth(depth: number): number {\n if (!Number.isFinite(depth) || depth < 0) {\n return 0;\n }\n return Math.min(Math.floor(depth), MAX_TERMINAL_DEPTH);\n}\n\nfunction safePrint(line = \"\"): void {\n try {\n console.log(line);\n } catch {\n /* never break callers */\n }\n}\n\n/** Indentation string for a nesting depth (capped, never negative). */\nexport function getIndent(depth: number): string {\n return TERMINAL_INDENT.repeat(normalizeDepth(depth));\n}\n\n/** Truncates a display name for terminal use; invalid input becomes `\"unnamed\"`. */\nexport function formatTerminalName(name: string): string {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n return \"unnamed\";\n }\n return truncateName(name, MAX_TERMINAL_NAME_LENGTH);\n}\n\nfunction getStatusIcon(status: StepStatus | RunStatus): string {\n if (status === \"success\") return chalk.green(\"✔\");\n if (status === \"error\") return chalk.red(\"✖\");\n return chalk.yellow(\"⏳\");\n}\n\n/** Renders a single step line (colored); does not consult silent mode. */\nexport function renderStepLine(\n name: string,\n durationMs: number | undefined,\n status: StepStatus,\n depth?: number,\n): string {\n try {\n const nm = formatTerminalName(name);\n const ind = getIndent(depth ?? 0);\n if (status === \"running\" && durationMs === undefined) {\n return `${ind}${chalk.yellow(\"⏳\")} ${nm}`;\n }\n const hasDur =\n durationMs !== undefined && Number.isFinite(durationMs as number);\n const dur = hasDur ? formatDuration(durationMs as number) : undefined;\n if (status === \"running\") {\n return dur !== undefined\n ? `${ind}${chalk.yellow(\"⏳\")} ${nm} (${dur})`\n : `${ind}${chalk.yellow(\"⏳\")} ${nm}`;\n }\n if (!hasDur || dur === undefined) {\n return `${ind}${chalk.yellow(\"⏳\")} ${nm}`;\n }\n if (status === \"success\") {\n return `${ind}${getStatusIcon(\"success\")} ${nm} (${dur})`;\n }\n return `${ind}${getStatusIcon(\"error\")} ${nm} (${dur})`;\n } catch {\n return \"\";\n }\n}\n\n/** Renders an error summary line (no stack in MVP). */\nexport function renderErrorLine(error: ErrorInfo, depth?: number): string {\n try {\n const msg =\n typeof error.message === \"string\" ? error.message : \"\";\n const ind = getIndent((depth ?? 0) + 1);\n return `${ind}Error: ${msg}`;\n } catch {\n return \"\";\n }\n}\n\n/** Plain-text run summary lines (no chalk) for stable testing and CLI reuse. */\nexport function renderRunSummary(\n durationMs: number,\n status: RunStatus,\n traceFilePath?: string,\n): string[] {\n try {\n const dur = Number.isFinite(durationMs)\n ? formatDuration(durationMs)\n : formatDuration(0);\n const head =\n status === \"error\" ? `Failed in ${dur}` : `Completed in ${dur}`;\n const lines = [head];\n if (traceFilePath !== undefined && traceFilePath.trim() !== \"\") {\n lines.push(`Trace: ${traceFilePath}`);\n }\n return lines;\n } catch {\n return [];\n }\n}\n\n/** Prints run header with icon and dim run id. */\nexport function printRunStart(runId: string, name: string): void {\n if (isSilentContext()) return;\n try {\n safePrint(\"\");\n const header = `${chalk.cyan.bold(\"🔍 AgentInspect:\")} ${formatTerminalName(name)} ${chalk.dim(`(${runId})`)}`;\n safePrint(header);\n } catch {\n /* noop */\n }\n}\n\n/** Prints a running step line. */\nexport function printStepStart(name: string, depth = 0): void {\n if (isSilentContext()) return;\n try {\n safePrint(renderStepLine(name, undefined, \"running\", depth));\n } catch {\n /* noop */\n }\n}\n\n/** Prints a completed step line with duration and status icon. */\nexport function printStepComplete(\n name: string,\n durationMs: number,\n status: StepStatus,\n depth = 0,\n): void {\n if (isSilentContext()) return;\n try {\n safePrint(renderStepLine(name, durationMs, status, depth));\n } catch {\n /* noop */\n }\n}\n\n/** Prints a structured error line (message only, no stack). */\nexport function printError(error: ErrorInfo, depth = 0): void {\n if (isSilentContext()) return;\n try {\n safePrint(renderErrorLine(error, depth));\n } catch {\n /* noop */\n }\n}\n\n/** Prints run completion summary and optional trace path. */\nexport function printRunComplete(\n _name: string,\n _runId: string,\n durationMs: number,\n status: RunStatus,\n traceFilePath?: string,\n): void {\n if (isSilentContext()) return;\n try {\n const lines = renderRunSummary(durationMs, status, traceFilePath);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n if (i === 0) {\n const color =\n status === \"error\"\n ? chalk.red\n : status === \"running\"\n ? chalk.yellow\n : chalk.green;\n safePrint(color(line));\n } else {\n safePrint(chalk.dim(line));\n }\n }\n } catch {\n /* noop */\n }\n}\n\n/** Prints which step failed. */\nexport function printFailedAt(stepName: string): void {\n if (isSilentContext()) return;\n try {\n safePrint(`Failed at: ${formatTerminalName(stepName)}`);\n } catch {\n /* noop */\n }\n}\n","import {\n getCurrentContext,\n getCurrentDepth,\n getParentStepId,\n getTraceSafetyFromContext,\n runWithStepContext,\n} from \"./context.js\";\nimport type { StepOptions, StepType, TraceEvent } from \"./types.js\";\nimport { writeTraceEvent } from \"./storage.js\";\nimport { printFailedAt, printError, printStepComplete, printStepStart } from \"./terminal.js\";\nimport { prepareTraceEventForDisk } from \"./trace-event-safety.js\";\nimport { createStepId, formatError, truncateName, warn } from \"./utils.js\";\n\nfunction normalizeStepName(name: unknown): string {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n return \"unnamed-step\";\n }\n return truncateName(name.trim(), 100);\n}\n\nasync function safeInstrumentation(\n label: string,\n op: () => void | Promise<void>,\n): Promise<void> {\n try {\n await Promise.resolve(op());\n } catch (e) {\n warn(`step: ${label}`, e);\n }\n}\n\nasync function stepImpl<T>(\n name: string,\n fn: () => Promise<T> | T,\n options?: StepOptions,\n): Promise<T> {\n if (typeof fn !== \"function\") {\n throw new TypeError(\"step requires `fn` to be a function\");\n }\n\n const stepName = normalizeStepName(name);\n const context = getCurrentContext();\n\n if (!context) {\n warn(\"step() called outside inspectRun(); executing without instrumentation\");\n return Promise.resolve(fn());\n }\n\n const stepId = createStepId();\n const renderDepth = getCurrentDepth();\n const parentId = getParentStepId();\n const stepType: StepType = options?.type ?? \"logic\";\n const metadata = options?.metadata;\n const traceSafety = getTraceSafetyFromContext();\n const startTime = Date.now();\n\n await safeInstrumentation(\"writeTraceEvent(step_started)\", async () => {\n const started: TraceEvent = {\n schemaVersion: \"0.1\",\n event: \"step_started\",\n timestamp: startTime,\n runId: context.runId,\n stepId,\n ...(typeof parentId === \"string\" && parentId.trim() !== \"\"\n ? { parentId }\n : {}),\n name: stepName,\n type: stepType,\n startTime,\n ...(metadata !== undefined ? { metadata } : {}),\n };\n const safe =\n traceSafety !== undefined\n ? prepareTraceEventForDisk(started, traceSafety)\n : started;\n await writeTraceEvent(safe, context.traceDir);\n });\n\n await safeInstrumentation(\"printStepStart\", () => {\n printStepStart(stepName, renderDepth);\n });\n\n let result: T;\n try {\n result = await runWithStepContext(stepId, async () => {\n return await Promise.resolve(fn());\n });\n } catch (userError) {\n const endTime = Date.now();\n const durationMs = endTime - startTime;\n const formatted = formatError(userError);\n\n await safeInstrumentation(\"writeTraceEvent(step_completed error)\", async () => {\n const completed: TraceEvent = {\n schemaVersion: \"0.1\",\n event: \"step_completed\",\n timestamp: endTime,\n runId: context.runId,\n stepId,\n status: \"error\",\n endTime,\n durationMs,\n error: formatted,\n };\n const safe =\n traceSafety !== undefined\n ? prepareTraceEventForDisk(completed, traceSafety)\n : completed;\n await writeTraceEvent(safe, context.traceDir);\n });\n\n await safeInstrumentation(\"printStepComplete(error)\", () => {\n printStepComplete(stepName, durationMs, \"error\", renderDepth);\n });\n await safeInstrumentation(\"printError\", () => {\n printError(formatted, renderDepth);\n });\n await safeInstrumentation(\"printFailedAt\", () => {\n printFailedAt(stepName);\n });\n\n throw userError;\n }\n\n const endTime = Date.now();\n const durationMs = endTime - startTime;\n\n await safeInstrumentation(\"writeTraceEvent(step_completed success)\", async () => {\n const completed: TraceEvent = {\n schemaVersion: \"0.1\",\n event: \"step_completed\",\n timestamp: endTime,\n runId: context.runId,\n stepId,\n status: \"success\",\n endTime,\n durationMs,\n };\n const safe =\n traceSafety !== undefined\n ? prepareTraceEventForDisk(completed, traceSafety)\n : completed;\n await writeTraceEvent(safe, context.traceDir);\n });\n\n await safeInstrumentation(\"printStepComplete(success)\", () => {\n printStepComplete(stepName, durationMs, \"success\", renderDepth);\n });\n\n return result;\n}\n\n/**\n * Stable v1.0 API for instrumenting a named step inside an AgentInspect run.\n *\n * Callable step tracer plus {@link step.llm} and {@link step.tool} shortcuts.\n */\nexport type StepFunction = {\n <T>(name: string, fn: () => Promise<T> | T, options?: StepOptions): Promise<T>;\n llm: <T>(model: string, fn: () => Promise<T> | T) => Promise<T>;\n tool: <T>(toolName: string, fn: () => Promise<T> | T) => Promise<T>;\n};\n\nasync function stepLlm<T>(model: string, fn: () => Promise<T> | T): Promise<T> {\n const modelName =\n typeof model === \"string\" && model.trim() !== \"\"\n ? model.trim()\n : \"unknown-model\";\n return stepImpl<T>(`llm:${modelName}`, fn, {\n type: \"llm\",\n metadata: { model: modelName },\n });\n}\n\nasync function stepTool<T>(\n toolName: string,\n fn: () => Promise<T> | T,\n): Promise<T> {\n const normalized =\n typeof toolName === \"string\" && toolName.trim() !== \"\"\n ? toolName.trim()\n : \"unknown-tool\";\n return stepImpl<T>(`tool:${normalized}`, fn, {\n type: \"tool\",\n metadata: { toolName: normalized },\n });\n}\n\n/**\n * Traces a named unit of work inside `inspectRun` (`step_started` / `step_completed`, optional terminal).\n * Outside a run, executes `fn` with a warn only. Preserves return values and rethrows user errors unchanged.\n *\n * - `step.llm(model, fn)` — `type: \"llm\"`, `metadata.model` (no SDK calls or token counting).\n * - `step.tool(toolName, fn)` — `type: \"tool\"`, `metadata.toolName` (no framework interception).\n */\nexport const step = Object.assign(stepImpl, {\n llm: stepLlm,\n tool: stepTool,\n}) as StepFunction;\n","import { step } from \"agent-inspect\";\n\nimport { hashServerUrl, summarizeMcpValue } from \"./summarize.js\";\nimport type {\n McpClientLike,\n McpClientTracerOptions,\n McpTraceMetadata,\n} from \"./types.js\";\n\nlet toolCallCounter = 0;\n\nfunction nextToolCallId(prefix?: string): string {\n toolCallCounter += 1;\n const base = prefix?.trim() || \"mcp\";\n return `${base}-${toolCallCounter}`;\n}\n\nfunction baseMetadata(\n options: McpClientTracerOptions,\n overrides: Partial<McpTraceMetadata> = {},\n): Record<string, unknown> {\n const metadata: McpTraceMetadata = {\n source: { type: \"mcp-client\" },\n ...(options.serverName ? { mcpServerName: options.serverName } : {}),\n ...(options.serverUrl\n ? { mcpServerUrlHash: hashServerUrl(options.serverUrl) }\n : {}),\n ...(options.sessionId ? { sessionId: options.sessionId } : {}),\n ...overrides,\n };\n return { ...(options.metadata ?? {}), ...metadata };\n}\n\n/**\n * Wraps an MCP client so tools/list and tools/call emit local tool steps.\n * Telemetry only — does not proxy network behavior beyond the wrapped client.\n */\nexport function wrapMcpClient<T extends McpClientLike>(\n client: T,\n options: McpClientTracerOptions = {},\n): T {\n const maxSummaryLength = options.maxSummaryLength ?? 240;\n const wrapped = { ...client } as T;\n\n if (typeof client.listTools === \"function\") {\n const listTools = client.listTools.bind(client);\n wrapped.listTools = async (params?: unknown) =>\n step(\n \"mcp:tools/list\",\n async () => {\n const result = await listTools(params);\n return result;\n },\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: \"tools/list\",\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n }),\n },\n );\n }\n\n const callTool = client.callTool.bind(client);\n wrapped.callTool = async (params) =>\n step(\n `mcp:${params.name}`,\n async () => callTool(params),\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: params.name,\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n argumentSummary: summarizeMcpValue(\n params.arguments ?? {},\n maxSummaryLength,\n ),\n }),\n },\n );\n\n return wrapped;\n}\n\n/** @internal resets tool call ids for deterministic tests */\nexport function resetMcpToolCallIdsForTests(): void {\n toolCallCounter = 0;\n}\n"]}
1
+ {"version":3,"sources":["../src/summarize.ts","../../core/src/logs/redactor.ts","../../core/src/redaction-profiles.ts","../../core/src/types.ts","../../core/src/utils/duration.ts","../../core/src/utils.ts","../../core/src/storage.ts","../../core/src/trace-event-safety.ts","../../core/src/context.ts","../../core/src/terminal.ts","../../core/src/step.ts","../src/wrap.ts"],"names":["crypto","path","os","nanoid","formatDuration","mkdir","isRecord","appendFile","out","AsyncLocalStorage","chalk","endTime","durationMs"],"mappings":"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","file":"index.cjs","sourcesContent":["const DEFAULT_MAX_SUMMARY_LENGTH = 240;\n\nexport function summarizeMcpValue(\n value: unknown,\n maxLength = DEFAULT_MAX_SUMMARY_LENGTH,\n): string {\n let text: string;\n try {\n if (typeof value === \"string\") {\n text = value;\n } else {\n text = JSON.stringify(value);\n }\n } catch {\n text = String(value);\n }\n if (text.length <= maxLength) return text;\n return `${text.slice(0, Math.max(0, maxLength - 3))}...`;\n}\n\nexport function hashServerUrl(url: string): string {\n let hash = 0;\n for (let i = 0; i < url.length; i += 1) {\n hash = (hash * 31 + url.charCodeAt(i)) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n","import crypto from \"node:crypto\";\n\nimport type { RedactionRule } from \"../types/log-config.js\";\n\nexport const DEFAULT_REDACT_KEYS = [\n \"authorization\",\n \"cookie\",\n \"token\",\n \"apiKey\",\n \"password\",\n \"secret\",\n \"email\",\n] as const;\n\nexport interface RedactorOptions {\n rules?: RedactionRule[];\n /** Additional exact keys (case-insensitive) to redact in addition to defaults. */\n extraKeys?: readonly string[];\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction toKey(s: string): string {\n return s.toLowerCase();\n}\n\nfunction stableHash(value: string): string {\n const h = crypto.createHash(\"sha256\").update(value, \"utf8\").digest(\"hex\");\n return h.slice(0, 8);\n}\n\ntype CompiledRule =\n | { key: string; strategy: \"full\" }\n | { key: string; strategy: \"prefix\"; keep: number }\n | { key: string; strategy: \"hash\" };\n\nfunction compileRules(\n rules?: RedactionRule[],\n extraKeys?: readonly string[],\n): CompiledRule[] {\n const out = new Map<string, CompiledRule>();\n\n const set = (r: CompiledRule) => {\n const k = toKey(r.key);\n out.set(k, { ...r, key: k } as CompiledRule);\n };\n\n for (const k of DEFAULT_REDACT_KEYS) {\n set({ key: k, strategy: \"full\" });\n }\n\n for (const k of extraKeys ?? []) {\n if (typeof k === \"string\" && k.length > 0) {\n set({ key: k, strategy: \"full\" });\n }\n }\n\n for (const r of rules ?? []) {\n if (typeof r === \"string\") {\n set({ key: r, strategy: \"full\" });\n continue;\n }\n const key = r.key;\n if (r.strategy === \"full\") set({ key, strategy: \"full\" });\n if (r.strategy === \"hash\") set({ key, strategy: \"hash\" });\n if (r.strategy === \"prefix\") {\n set({ key, strategy: \"prefix\", keep: typeof r.keep === \"number\" ? r.keep : 8 });\n }\n }\n\n return [...out.values()];\n}\n\nexport class Redactor {\n readonly #rules: CompiledRule[];\n\n constructor(options?: RedactorOptions) {\n this.#rules = compileRules(options?.rules, options?.extraKeys);\n }\n\n redactValue(key: string, value: unknown): unknown {\n const k = toKey(key);\n const rule = this.#rules.find((r) => r.key === k);\n if (!rule) {\n return this.#redactNested(value);\n }\n\n if (rule.strategy === \"full\") return \"[REDACTED]\";\n const asString =\n typeof value === \"string\"\n ? value\n : typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\"\n ? String(value)\n : undefined;\n\n if (rule.strategy === \"prefix\") {\n if (asString === undefined) return \"[REDACTED]\";\n const keep = Math.max(0, Math.floor(rule.keep));\n return asString.length <= keep ? `${asString}…` : `${asString.slice(0, keep)}…`;\n }\n\n if (rule.strategy === \"hash\") {\n if (asString === undefined) return \"[HASH:unknown]\";\n return `[HASH:${stableHash(asString)}]`;\n }\n\n return this.#redactNested(value);\n }\n\n redactRecord(record: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(record)) {\n out[k] = this.redactValue(k, v);\n }\n return out;\n }\n\n #redactNested(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((v) => this.#redactNested(v));\n }\n if (isRecord(value)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n out[k] = this.redactValue(k, v);\n }\n return out;\n }\n return value;\n }\n}\n\n","import type { RedactionProfile } from \"./types.js\";\n\n/** Extra keys redacted under the `share` profile (in addition to {@link DEFAULT_REDACT_KEYS}). */\nexport const SHARE_PROFILE_EXTRA_KEYS = [\n \"userEmail\",\n \"customerEmail\",\n \"phone\",\n \"phoneNumber\",\n \"address\",\n \"ip\",\n \"ipAddress\",\n \"sessionId\",\n \"requestId\",\n \"correlationId\",\n \"decisionId\",\n \"groupId\",\n \"customerId\",\n \"userId\",\n \"accountId\",\n \"tenantId\",\n \"orgId\",\n \"organizationId\",\n \"traceId\",\n \"spanId\",\n \"parentSpanId\",\n] as const;\n\n/** Extra keys redacted under the `strict` profile (in addition to share keys). */\nexport const STRICT_PROFILE_EXTRA_KEYS = [\n \"prompt\",\n \"completion\",\n \"input\",\n \"output\",\n \"inputPreview\",\n \"outputPreview\",\n \"message\",\n \"messages\",\n \"transcript\",\n \"context\",\n \"document\",\n \"documents\",\n \"chunk\",\n \"chunks\",\n \"retrieval\",\n \"query\",\n] as const;\n\nexport interface ResolvedRedactionProfile {\n profile: RedactionProfile;\n extraKeys: readonly string[];\n maxMetadataValueLengthCap?: number;\n maxPreviewLengthCap?: number;\n}\n\n/** Resolves named profile behavior (keys + metadata string caps). */\nexport function resolveRedactionProfile(\n profile: RedactionProfile = \"local\",\n): ResolvedRedactionProfile {\n switch (profile) {\n case \"local\":\n return { profile: \"local\", extraKeys: [] };\n case \"share\":\n return {\n profile: \"share\",\n extraKeys: SHARE_PROFILE_EXTRA_KEYS,\n maxMetadataValueLengthCap: 500,\n maxPreviewLengthCap: 200,\n };\n case \"strict\":\n return {\n profile: \"strict\",\n extraKeys: [...SHARE_PROFILE_EXTRA_KEYS, ...STRICT_PROFILE_EXTRA_KEYS],\n maxMetadataValueLengthCap: 200,\n maxPreviewLengthCap: 80,\n };\n default:\n return { profile: \"local\", extraKeys: [] };\n }\n}\n\nfunction isPreviewKey(key: string): boolean {\n return key.toLowerCase().includes(\"preview\");\n}\n\n/**\n * Applies profile metadata string caps. User-provided lower limits are preserved.\n */\nexport function applyProfileMetadataCaps(\n maxMetadataValueLength: number,\n maxPreviewLength: number,\n resolved: ResolvedRedactionProfile,\n): { maxMetadataValueLength: number; maxPreviewLength: number } {\n let meta = maxMetadataValueLength;\n let preview = maxPreviewLength;\n\n if (resolved.maxMetadataValueLengthCap !== undefined) {\n meta = Math.min(meta, resolved.maxMetadataValueLengthCap);\n }\n if (resolved.maxPreviewLengthCap !== undefined) {\n preview = Math.min(preview, resolved.maxPreviewLengthCap);\n }\n\n return { maxMetadataValueLength: meta, maxPreviewLength: preview };\n}\n\nexport function truncateStringForProfile(\n value: string,\n key: string,\n maxMetadataValueLength: number,\n maxPreviewLength: number,\n): string {\n const max = isPreviewKey(key) ? maxPreviewLength : maxMetadataValueLength;\n if (max <= 0) return \"…\";\n if (value.length <= max) return value;\n return `${value.slice(0, max)}…`;\n}\n","import type { RedactionRule } from \"./types/log-config.js\";\n\n/**\n * Discriminator for what kind of work a {@link Step} represents.\n * `\"decision\"` captures agent branching/choices; other values cover runs, LLM calls, tools, and user-defined steps.\n */\nexport type StepType =\n | \"run\"\n | \"llm\"\n | \"tool\"\n | \"decision\"\n | \"logic\"\n | \"state\"\n | \"custom\";\n\n/** Lifecycle state of a single {@link Step}. */\nexport type StepStatus = \"running\" | \"success\" | \"error\";\n\n/** Lifecycle state of an entire {@link Run}. */\nexport type RunStatus = \"running\" | \"success\" | \"error\";\n\n/** Structured error attached to a run or step when status is `\"error\"`. */\nexport interface ErrorInfo {\n message: string;\n stack?: string;\n}\n\n/**\n * Optional token counts for a step (e.g. LLM usage).\n * Reserved for future roadmap; MVP does not compute or persist token usage.\n */\nexport interface TokenMetadata {\n input?: number;\n output?: number;\n total?: number;\n cached?: number;\n}\n\n/** Arbitrary structured fields for a step; safe extensions use string keys. */\nexport interface StepMetadata {\n model?: string;\n toolName?: string;\n tokens?: TokenMetadata;\n retryCount?: number;\n [key: string]: unknown;\n}\n\n/**\n * One traced agent run (root of an execution tree).\n * MVP intentionally omits `input` / `output` on the run to limit PII, secrets, and serialization risk.\n */\nexport interface Run {\n id: string;\n name: string;\n status: RunStatus;\n startTime: number;\n endTime?: number;\n durationMs?: number;\n error?: ErrorInfo;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * One node in the execution tree under a {@link Run}.\n * MVP intentionally omits `input` / `output`; capture/redaction may come in a later version.\n */\nexport interface Step {\n id: string;\n runId: string;\n parentId?: string;\n name: string;\n type: StepType;\n status: StepStatus;\n startTime: number;\n endTime?: number;\n durationMs?: number;\n error?: ErrorInfo;\n metadata?: StepMetadata;\n}\n\n/** Version of the JSONL trace line schema consumed by AgentInspect tooling. */\nexport type TraceSchemaVersion = \"0.1\";\n\n/**\n * Status for lightweight trace metadata extraction.\n * `\"unknown\"` means the file contained valid events but a run status could not be determined safely.\n */\nexport type TraceMetadataStatus = \"success\" | \"error\" | \"running\" | \"unknown\";\n\nexport interface TraceMetadata {\n runId: string;\n name?: string;\n status: TraceMetadataStatus;\n startedAt?: number;\n endedAt?: number;\n durationMs?: number;\n eventCount: number;\n filePath: string;\n fileSize: number;\n createdAt: Date;\n}\n\nexport interface RunSummary {\n runId: string;\n name?: string;\n status: TraceMetadataStatus;\n durationMs?: number;\n totalSteps: number;\n llmSteps: number;\n toolSteps: number;\n logicSteps: number;\n errorSteps: number;\n maxDepth: number;\n longestStep?: {\n name: string;\n durationMs: number;\n type: string;\n };\n totalTokens?: {\n input: number;\n output: number;\n /** Present only when every token-bearing step has a supplied or derivable total. */\n total?: number;\n /** Sum of supplied cached counts; cached is not added to total. */\n cached?: number;\n };\n}\n\n/** Fields shared by every persisted trace event line. */\nexport interface TraceEventBase {\n schemaVersion: TraceSchemaVersion;\n event: string;\n timestamp: number;\n}\n\n/** Emitted when a run begins. */\nexport interface RunStartedEvent extends TraceEventBase {\n event: \"run_started\";\n runId: string;\n name: string;\n startTime: number;\n metadata?: Record<string, unknown>;\n}\n\n/** Emitted when a run finishes successfully or with an error. */\nexport interface RunCompletedEvent extends TraceEventBase {\n event: \"run_completed\";\n runId: string;\n status: \"success\" | \"error\";\n endTime: number;\n durationMs: number;\n error?: ErrorInfo;\n}\n\n/** Emitted when a step begins (including nested steps under `parentId`). */\nexport interface StepStartedEvent extends TraceEventBase {\n event: \"step_started\";\n runId: string;\n stepId: string;\n parentId?: string;\n name: string;\n type: StepType;\n startTime: number;\n metadata?: StepMetadata;\n}\n\n/**\n * Emitted when a step finishes (success or failure).\n * Failures use `status: \"error\"` and optional {@link ErrorInfo}; there is no separate `step_failed` event in MVP.\n */\nexport interface StepCompletedEvent extends TraceEventBase {\n event: \"step_completed\";\n runId: string;\n stepId: string;\n status: \"success\" | \"error\";\n endTime: number;\n durationMs: number;\n error?: ErrorInfo;\n}\n\n/** Emitted when an external-world outcome is observed (v4.4+). */\nexport interface OutcomeObservedEvent extends TraceEventBase {\n event: \"outcome_observed\";\n runId: string;\n outcomeId: string;\n parentId?: string;\n name: string;\n expectation: string;\n status: \"passed\" | \"failed\" | \"unknown\" | \"skipped\";\n method?:\n | \"dom\"\n | \"accessibility\"\n | \"snapshot\"\n | \"network\"\n | \"storage\"\n | \"filesystem\"\n | \"database\"\n | \"queue\"\n | \"custom\";\n actual?: unknown;\n evidence?: unknown;\n observedAt: number;\n}\n\n/** Discriminated union of all MVP trace events written as JSONL lines. */\nexport type TraceEvent =\n | RunStartedEvent\n | RunCompletedEvent\n | StepStartedEvent\n | StepCompletedEvent\n | OutcomeObservedEvent;\n\n/** Named redaction presets for trace writing and share-safe exports (v1.3.0+). */\nexport type RedactionProfile = \"local\" | \"share\" | \"strict\";\n\n/** Optional correlation fields for grouping and cross-run tracing (v1.3.0+). */\nexport interface TraceCorrelationMetadata {\n correlationId?: string;\n requestId?: string;\n decisionId?: string;\n groupId?: string;\n}\n\n/** Options for `inspectRun()` and `maybeInspectRun()`. */\nexport interface InspectRunOptions extends TraceCorrelationMetadata {\n traceDir?: string;\n silent?: boolean;\n metadata?: Record<string, unknown>;\n /**\n * When `false`, runs `fn` with no trace file, no execution context, and no terminal output.\n * Omitted or `true` preserves default tracing behavior.\n */\n enabled?: boolean;\n /**\n * Redact sensitive metadata keys before writing JSONL. Default `true` (conservative keys).\n * Pass `false` to persist metadata as-is (explicit opt-out).\n */\n redact?: boolean | { rules?: RedactionRule[] };\n /**\n * Redaction preset for trace metadata. Default `local` (same keys as default redaction).\n * `share` and `strict` add extra key-based redaction and tighter string bounds.\n * Ignored when `redact: false`.\n */\n redactionProfile?: RedactionProfile;\n /** Max UTF-8 bytes for a serialized trace event line. Default 65536. */\n maxEventBytes?: number;\n /** Max length for string metadata values (non-preview keys). Default 2000. */\n maxMetadataValueLength?: number;\n /** Max length for preview-like metadata keys (contains `preview`). Default 500. */\n maxPreviewLength?: number;\n}\n\n/** Options passed when opening a logical step (implemented in a later step). */\nexport interface StepOptions {\n type?: StepType;\n metadata?: StepMetadata;\n}\n\n/** Options for `observe()` — same surface as {@link InspectRunOptions} in MVP. */\nexport type ObserveOptions = InspectRunOptions;\n\n/**\n * Resolved settings for the active run while tracing is enabled.\n * Populated by runtime code in a later step; defined here for `context.ts`.\n */\nexport interface ExecutionContext {\n runId: string;\n runName: string;\n traceDir: string;\n silent: boolean;\n metadata?: Record<string, unknown>;\n}\n\n/** Stack position of the step currently executing (used by future context tracking). */\nexport interface ActiveStepContext {\n stepId: string;\n parentId?: string;\n depth: number;\n}\n\nconst STEP_TYPES: readonly StepType[] = [\n \"run\",\n \"llm\",\n \"tool\",\n \"decision\",\n \"logic\",\n \"state\",\n \"custom\",\n] as const;\n\nconst STEP_STATUSES: readonly StepStatus[] = [\n \"running\",\n \"success\",\n \"error\",\n] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Returns true if `value` is one of the MVP {@link StepType} literals. */\nexport function isStepType(value: unknown): value is StepType {\n return (\n typeof value === \"string\" &&\n (STEP_TYPES as readonly string[]).includes(value)\n );\n}\n\n/** Returns true if `value` is one of the MVP {@link StepStatus} literals. */\nexport function isStepStatus(value: unknown): value is StepStatus {\n return (\n typeof value === \"string\" &&\n (STEP_STATUSES as readonly string[]).includes(value)\n );\n}\n\n/**\n * Narrowing guard for a {@link TraceEvent} object with required MVP fields.\n * Does not deeply validate optional `metadata` shapes.\n */\nexport function isTraceEvent(value: unknown): value is TraceEvent {\n if (!isRecord(value)) return false;\n if (value.schemaVersion !== \"0.1\") return false;\n if (typeof value.timestamp !== \"number\") return false;\n if (typeof value.event !== \"string\") return false;\n\n switch (value.event) {\n case \"run_started\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.name === \"string\" &&\n typeof value.startTime === \"number\"\n );\n }\n case \"run_completed\": {\n return (\n typeof value.runId === \"string\" &&\n (value.status === \"success\" || value.status === \"error\") &&\n typeof value.endTime === \"number\" &&\n typeof value.durationMs === \"number\"\n );\n }\n case \"step_started\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.stepId === \"string\" &&\n typeof value.name === \"string\" &&\n isStepType(value.type) &&\n typeof value.startTime === \"number\"\n );\n }\n case \"step_completed\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.stepId === \"string\" &&\n (value.status === \"success\" || value.status === \"error\") &&\n typeof value.endTime === \"number\" &&\n typeof value.durationMs === \"number\"\n );\n }\n case \"outcome_observed\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.outcomeId === \"string\" &&\n typeof value.name === \"string\" &&\n typeof value.expectation === \"string\" &&\n (value.status === \"passed\" ||\n value.status === \"failed\" ||\n value.status === \"unknown\" ||\n value.status === \"skipped\") &&\n typeof value.observedAt === \"number\"\n );\n }\n default:\n return false;\n }\n}\n","/**\n * v0.2 shared duration utilities.\n *\n * `parseDuration` is used for filters such as \"since\" / \"older-than\".\n * `formatDuration` is used for compact display in CLI and summaries.\n */\n\nexport function parseDuration(duration: string): number {\n const raw = typeof duration === \"string\" ? duration.trim() : \"\";\n const match = raw.match(/^(\\d+)(ms|[smhd])$/);\n if (!match) {\n throw new Error(\n `Invalid duration format: ${duration}. Use a positive integer followed by ms, s, m, h, or d (e.g. 500ms, 30s, 5m, 2h, 7d).`,\n );\n }\n\n const amount = Number.parseInt(match[1], 10);\n const unit = match[2];\n\n if (!Number.isFinite(amount) || amount <= 0) {\n throw new Error(\n `Invalid duration amount: ${duration}. Amount must be a positive integer.`,\n );\n }\n\n switch (unit) {\n case \"ms\":\n return amount;\n case \"s\":\n return amount * 1000;\n case \"m\":\n return amount * 60 * 1000;\n case \"h\":\n return amount * 60 * 60 * 1000;\n case \"d\":\n return amount * 24 * 60 * 60 * 1000;\n default: {\n // Should be unreachable due to regex.\n throw new Error(`Unknown duration unit: ${unit}`);\n }\n }\n}\n\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms)) {\n return \"0ms\";\n }\n if (ms < 0) {\n throw new Error(`formatDuration: ms must be non-negative (got ${ms})`);\n }\n if (ms < 1000) {\n return `${Math.floor(ms)}ms`;\n }\n if (ms < 60_000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n if (ms < 3_600_000) {\n return `${(ms / 60_000).toFixed(1)}m`;\n }\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\n","import { mkdir } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nimport { nanoid } from \"nanoid\";\n\nimport type { ErrorInfo } from \"./types.js\";\nimport { formatDuration as formatDurationV2 } from \"./utils/duration.js\";\n\n/** Default folder under the user home for AgentInspect data. */\nexport const DEFAULT_TRACE_DIR_NAME = \".agent-inspect\";\n\n/** Subfolder where JSONL run traces are stored. */\nexport const RUNS_DIR_NAME = \"runs\";\n\n/** Writable trace root when the default home path cannot be used. */\nexport const FALLBACK_TRACE_DIR = path.join(\n os.tmpdir(),\n \"agent-inspect\",\n RUNS_DIR_NAME,\n);\n\n/** Maximum display length for run/step names before truncation. */\nexport const MAX_NAME_LENGTH = 100;\n\n/** Returns `run_` + a 10-character nanoid segment. */\nexport function createRunId(): string {\n return `run_${nanoid(10)}`;\n}\n\n/** Returns `step_` + a 10-character nanoid segment. */\nexport function createStepId(): string {\n return `step_${nanoid(10)}`;\n}\n\n/** Formats a duration for CLI display (v0.2 rules). */\nexport function formatDuration(ms: number): string {\n return formatDurationV2(ms);\n}\n\n/**\n * Formats a Unix timestamp (ms) as local `YYYY-MM-DD HH:mm:ss`.\n * Invalid values yield `\"Invalid date\"` (no throw).\n */\nexport function formatTimestamp(timestamp: number): string {\n if (!Number.isFinite(timestamp)) {\n return \"Invalid date\";\n }\n const d = new Date(timestamp);\n if (Number.isNaN(d.getTime())) {\n return \"Invalid date\";\n }\n const y = d.getFullYear();\n const mo = String(d.getMonth() + 1).padStart(2, \"0\");\n const day = String(d.getDate()).padStart(2, \"0\");\n const h = String(d.getHours()).padStart(2, \"0\");\n const min = String(d.getMinutes()).padStart(2, \"0\");\n const s = String(d.getSeconds()).padStart(2, \"0\");\n return `${y}-${mo}-${day} ${h}:${min}:${s}`;\n}\n\n/**\n * Default directory for trace files: `~/DEFAULT_TRACE_DIR_NAME/RUNS_DIR_NAME`.\n * Falls back to {@link FALLBACK_TRACE_DIR} when home cannot be resolved.\n */\nexport function getDefaultTraceDir(): string {\n const envDir = process.env.AGENT_INSPECT_TRACE_DIR;\n if (typeof envDir === \"string\" && envDir.trim() !== \"\") {\n return envDir.trim();\n }\n try {\n const home = os.homedir();\n if (typeof home !== \"string\" || home.trim() === \"\") {\n return FALLBACK_TRACE_DIR;\n }\n return path.join(home, DEFAULT_TRACE_DIR_NAME, RUNS_DIR_NAME);\n } catch {\n return FALLBACK_TRACE_DIR;\n }\n}\n\n/**\n * Full path to the JSONL trace file for a run.\n * `runId` is passed through `path.basename` to avoid traversal; empty ids become `run_unknown`.\n */\nexport function getTraceFilePath(runId: string, traceDir?: string): string {\n const baseDir = traceDir ?? getDefaultTraceDir();\n let safeId =\n typeof runId === \"string\" && runId.trim() !== \"\" ? runId.trim() : \"run_unknown\";\n safeId = path.basename(safeId);\n if (safeId === \"\" || safeId === \".\" || safeId === \"..\") {\n safeId = \"run_unknown\";\n }\n return path.join(baseDir, `${safeId}.jsonl`);\n}\n\n/**\n * Ensures a trace directory exists (recursive). Tries {@link FALLBACK_TRACE_DIR} on failure.\n * Returns the directory path that callers should prefer: primary, fallback, or original if both mkdir attempts fail.\n * Emits concise `[AgentInspect]` warnings on failure; never throws.\n */\nexport async function ensureTraceDir(traceDir: string): Promise<string> {\n const primary = path.resolve(traceDir);\n try {\n await mkdir(primary, { recursive: true });\n return primary;\n } catch {\n warn(`Failed to create trace directory: ${primary}`);\n const fallback = path.resolve(FALLBACK_TRACE_DIR);\n try {\n await mkdir(fallback, { recursive: true });\n return fallback;\n } catch {\n warn(`Failed to create fallback trace directory: ${fallback}`);\n return primary;\n }\n }\n}\n\n/**\n * Normalizes any thrown/caught value into {@link ErrorInfo}.\n * Never throws (circular structures and non-JSON values fall back to a generic message).\n */\nexport function formatError(error: unknown): ErrorInfo {\n if (error instanceof Error) {\n const out: ErrorInfo = { message: error.message };\n if (typeof error.stack === \"string\" && error.stack.length > 0) {\n out.stack = error.stack;\n }\n return out;\n }\n if (typeof error === \"string\") {\n return { message: error };\n }\n if (error === null) {\n return { message: \"Unknown error: null\" };\n }\n if (error === undefined) {\n return { message: \"Unknown error: undefined\" };\n }\n if (\n typeof error === \"number\" ||\n typeof error === \"boolean\" ||\n typeof error === \"bigint\"\n ) {\n return { message: String(error) };\n }\n if (typeof error === \"object\") {\n try {\n return { message: JSON.stringify(error) };\n } catch {\n return { message: \"Unknown error\" };\n }\n }\n return { message: \"Unknown error\" };\n}\n\n/**\n * Truncates a display name to `maxLength`, appending `\"...\"` when shortened.\n * Empty or non-string input becomes `\"unnamed\"`.\n */\nexport function truncateName(name: string, maxLength = MAX_NAME_LENGTH): string {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n return \"unnamed\";\n }\n const trimmed = name.trim();\n if (trimmed.length <= maxLength) {\n return trimmed;\n }\n const ellipsis = \"...\";\n const head = Math.max(0, maxLength - ellipsis.length);\n return `${trimmed.slice(0, head)}${ellipsis}`;\n}\n\n/**\n * Instrumentation-only warning to stderr. Not a general-purpose logger.\n * Optional `error` is summarized via {@link formatError} (message only).\n */\nexport function warn(message: string, error?: unknown): void {\n const base = `[AgentInspect] ${message}`;\n if (error === undefined) {\n console.warn(base);\n return;\n }\n console.warn(`${base}: ${formatError(error).message}`);\n}\n","import { appendFile, readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { TraceEvent } from \"./types.js\";\nimport { isStepType } from \"./types.js\";\nimport {\n DEFAULT_MAX_EVENT_BYTES,\n prepareTraceEventForDisk,\n resolveTraceSafetyOptions,\n} from \"./trace-event-safety.js\";\nimport { parseTraceJsonl } from \"./read-trace.js\";\nimport {\n ensureTraceDir,\n FALLBACK_TRACE_DIR,\n getTraceFilePath,\n warn,\n} from \"./utils.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction nonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim() !== \"\";\n}\n\nfunction finiteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction optionalErrorInfo(value: unknown): boolean {\n if (value === undefined) return true;\n if (!isRecord(value)) return false;\n if (typeof value.message !== \"string\") return false;\n if (\"stack\" in value && value.stack !== undefined) {\n if (typeof value.stack !== \"string\") return false;\n }\n return true;\n}\n\n/**\n * Strict MVP validation before writing JSONL. Rejects empty ids, non-finite times, and malformed payloads.\n */\nexport function validateEvent(event: unknown): event is TraceEvent {\n if (!isRecord(event)) return false;\n if (event.schemaVersion !== \"0.1\") return false;\n if (!finiteNumber(event.timestamp)) return false;\n if (typeof event.event !== \"string\") return false;\n\n switch (event.event) {\n case \"run_started\": {\n if (\n !nonEmptyString(event.runId) ||\n !nonEmptyString(event.name) ||\n !finiteNumber(event.startTime)\n ) {\n return false;\n }\n if (event.metadata !== undefined && !isRecord(event.metadata)) {\n return false;\n }\n return true;\n }\n case \"run_completed\": {\n return (\n nonEmptyString(event.runId) &&\n (event.status === \"success\" || event.status === \"error\") &&\n finiteNumber(event.endTime) &&\n finiteNumber(event.durationMs) &&\n optionalErrorInfo(event.error)\n );\n }\n case \"step_started\": {\n if (\n !nonEmptyString(event.runId) ||\n !nonEmptyString(event.stepId) ||\n !nonEmptyString(event.name) ||\n !isStepType(event.type) ||\n !finiteNumber(event.startTime)\n ) {\n return false;\n }\n if (event.parentId !== undefined && typeof event.parentId !== \"string\") {\n return false;\n }\n if (event.metadata !== undefined && !isRecord(event.metadata)) {\n return false;\n }\n return true;\n }\n case \"step_completed\": {\n return (\n nonEmptyString(event.runId) &&\n nonEmptyString(event.stepId) &&\n (event.status === \"success\" || event.status === \"error\") &&\n finiteNumber(event.endTime) &&\n finiteNumber(event.durationMs) &&\n optionalErrorInfo(event.error)\n );\n }\n case \"outcome_observed\": {\n return (\n nonEmptyString(event.runId) &&\n nonEmptyString(event.outcomeId) &&\n nonEmptyString(event.name) &&\n nonEmptyString(event.expectation) &&\n (event.status === \"passed\" ||\n event.status === \"failed\" ||\n event.status === \"unknown\" ||\n event.status === \"skipped\") &&\n finiteNumber(event.observedAt)\n );\n }\n default:\n return false;\n }\n}\n\n/** Serializes a trace line as compact JSON without a trailing newline. */\nexport function serializeEvent(event: TraceEvent): string {\n try {\n return JSON.stringify(event);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Creates (or truncates) an empty JSONL file for a run. Uses {@link ensureTraceDir} then {@link getTraceFilePath}.\n * On failure, retries once under {@link FALLBACK_TRACE_DIR}.\n */\nexport async function initializeTraceFile(\n runId: string,\n traceDir: string,\n): Promise<string | undefined> {\n try {\n const usable = await ensureTraceDir(traceDir);\n const filePath = getTraceFilePath(runId, usable);\n await writeFile(filePath, \"\", \"utf-8\");\n return filePath;\n } catch (e) {\n warn(\"Failed to initialize trace file\", e);\n }\n\n try {\n const usable = await ensureTraceDir(FALLBACK_TRACE_DIR);\n const filePath = getTraceFilePath(runId, usable);\n await writeFile(filePath, \"\", \"utf-8\");\n return filePath;\n } catch (e) {\n warn(\"Failed to initialize trace file on fallback directory\", e);\n return undefined;\n }\n}\n\n/**\n * Appends one validated JSONL line for `event.runId`. Falls back to {@link FALLBACK_TRACE_DIR} on append failure.\n */\nfunction ensureEventWithinBounds(event: TraceEvent): TraceEvent {\n const line = serializeEvent(event);\n if (line === \"\") return event;\n const bytes = Buffer.byteLength(line, \"utf8\");\n if (bytes <= DEFAULT_MAX_EVENT_BYTES) return event;\n return prepareTraceEventForDisk(event, resolveTraceSafetyOptions());\n}\n\nexport async function writeTraceEvent(\n event: TraceEvent,\n traceDir: string,\n): Promise<void> {\n const bounded = ensureEventWithinBounds(event);\n\n if (!validateEvent(bounded)) {\n warn(\"Skipped invalid trace event (validation failed)\");\n return;\n }\n\n const line = serializeEvent(bounded);\n if (line === \"\") {\n warn(\"Skipped trace event (serialization failed)\");\n return;\n }\n\n const payload = `${line}\\n`;\n\n const tryAppend = async (dir: string): Promise<boolean> => {\n try {\n const usable = await ensureTraceDir(dir);\n const filePath = getTraceFilePath(event.runId, usable);\n await appendFile(filePath, payload, \"utf-8\");\n return true;\n } catch {\n return false;\n }\n };\n\n if (await tryAppend(traceDir)) {\n return;\n }\n\n warn(`Failed to append trace event for run ${event.runId}`);\n\n if (await tryAppend(FALLBACK_TRACE_DIR)) {\n return;\n }\n\n warn(\"Failed to append trace event to fallback directory\");\n}\n\n/**\n * Reads raw JSONL file contents for a run, or `undefined` if missing or unreadable.\n */\nexport async function readTraceFile(\n runId: string,\n traceDir: string,\n): Promise<string | undefined> {\n try {\n const filePath = getTraceFilePath(runId, traceDir);\n return await readFile(filePath, \"utf-8\");\n } catch (e) {\n if (e && typeof e === \"object\" && \"code\" in e && e.code === \"ENOENT\") {\n return undefined;\n }\n warn(\"Unexpected error reading trace file\", e);\n return undefined;\n }\n}\n\n/**\n * Parses JSONL into validated {@link TraceEvent} rows (v0.1 native or v0.2 normalized).\n * Invalid lines are skipped with a warning.\n */\nexport async function readTraceEvents(\n runId: string,\n traceDir: string,\n): Promise<TraceEvent[]> {\n try {\n const filePath = getTraceFilePath(runId, traceDir);\n return await readTraceEventsFromFile(filePath);\n } catch (e) {\n warn(\"Failed to read trace events\", e);\n return [];\n }\n}\n\n/**\n * Reads and normalizes trace events from an exact file path.\n * Used by directory scans where the embedded run id may differ from the basename.\n */\nexport async function readTraceEventsFromFile(\n filePath: string,\n): Promise<TraceEvent[]> {\n try {\n const raw = await readFile(filePath, \"utf-8\");\n return parseTraceJsonl(raw, { validate: validateEvent }).events;\n } catch (e) {\n if (e && typeof e === \"object\" && \"code\" in e && e.code === \"ENOENT\") {\n return [];\n }\n warn(\"Failed to read trace events from file\", e);\n return [];\n }\n}\n\n/**\n * Lists `.jsonl` file names in `traceDir`, newest by mtime first (name sort as tie-breaker).\n */\nexport async function listTraceFiles(traceDir: string): Promise<string[]> {\n try {\n const usable = path.resolve(traceDir);\n const names = await readdir(usable);\n const jsonl = names.filter((n) => n.endsWith(\".jsonl\"));\n const withStat = await Promise.all(\n jsonl.map(async (name) => {\n try {\n const st = await stat(path.join(usable, name));\n return { name, mtime: st.mtimeMs };\n } catch {\n return { name, mtime: 0 };\n }\n }),\n );\n withStat.sort((a, b) => {\n if (b.mtime !== a.mtime) return b.mtime - a.mtime;\n return a.name.localeCompare(b.name);\n });\n return withStat.map((x) => x.name);\n } catch {\n return [];\n }\n}\n\n/** Maps a `.jsonl` file name to its run id (basename only; no traversal). */\nexport function getRunIdFromTraceFileName(fileName: string): string | undefined {\n try {\n const base = path.basename(fileName);\n if (!base.endsWith(\".jsonl\")) return undefined;\n const id = base.slice(0, -\".jsonl\".length);\n return id === \"\" ? undefined : id;\n } catch {\n return undefined;\n }\n}\n","import { Redactor } from \"./logs/redactor.js\";\nimport {\n applyProfileMetadataCaps,\n resolveRedactionProfile,\n type ResolvedRedactionProfile,\n} from \"./redaction-profiles.js\";\nimport { serializeEvent } from \"./storage.js\";\nimport type { RedactionRule } from \"./types/log-config.js\";\nimport {\n isPersistedInspectEvent,\n type PersistedInspectError,\n type PersistedInspectEvent,\n type PersistedTokenUsage,\n type PersistedTraceContext,\n} from \"./types/persisted-inspect-event.js\";\nimport type {\n InspectRunOptions,\n RedactionProfile,\n StepMetadata,\n TraceEvent,\n} from \"./types.js\";\n\n/** Default max length for string metadata values (non-preview keys). */\nexport const DEFAULT_MAX_METADATA_VALUE_LENGTH = 2000;\n\n/** Default max length for preview-like metadata keys (contains `preview`, case-insensitive). */\nexport const DEFAULT_MAX_PREVIEW_LENGTH = 500;\n\n/** Default max serialized JSONL line size in bytes (UTF-8). */\nexport const DEFAULT_MAX_EVENT_BYTES = 65_536;\n\n/** Resolved trace safety settings used at write time. */\nexport interface TraceSafetyOptions {\n redactEnabled: boolean;\n redactionRules?: RedactionRule[];\n redactionProfile: RedactionProfile;\n profileExtraKeys: readonly string[];\n maxMetadataValueLength: number;\n maxPreviewLength: number;\n maxEventBytes: number;\n}\n\nexport type { ResolvedRedactionProfile };\nexport { resolveRedactionProfile };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nconst KNOWN_PERSISTED_EVENT_FIELDS = new Set([\n \"schemaVersion\",\n \"eventId\",\n \"runId\",\n \"kind\",\n \"name\",\n \"parentId\",\n \"status\",\n \"timestamp\",\n \"startedAt\",\n \"endedAt\",\n \"durationMs\",\n \"confidence\",\n \"source\",\n \"attributes\",\n \"inputSummary\",\n \"outputSummary\",\n \"error\",\n \"tokenUsage\",\n \"trace\",\n]);\n\nfunction isSafeExtensionFieldName(key: string): boolean {\n return key !== \"__proto__\" && key !== \"constructor\" && key !== \"prototype\";\n}\n\nfunction isPreviewKey(key: string): boolean {\n return key.toLowerCase().includes(\"preview\");\n}\n\nfunction truncateString(value: string, maxLen: number): string {\n if (maxLen <= 0) return \"…\";\n if (value.length <= maxLen) return value;\n return `${value.slice(0, maxLen)}…`;\n}\n\nfunction byteLength(text: string): number {\n return Buffer.byteLength(text, \"utf8\");\n}\n\n/** Resolves {@link InspectRunOptions} trace safety fields with safe defaults. */\nexport function resolveTraceSafetyOptions(\n options?: Pick<\n InspectRunOptions,\n | \"redact\"\n | \"redactionProfile\"\n | \"maxEventBytes\"\n | \"maxMetadataValueLength\"\n | \"maxPreviewLength\"\n >,\n): TraceSafetyOptions {\n const redact = options?.redact;\n let redactEnabled = true;\n let redactionRules: RedactionRule[] | undefined;\n\n if (redact === false) {\n redactEnabled = false;\n } else if (redact === true || redact === undefined) {\n redactEnabled = true;\n } else if (isRecord(redact)) {\n redactEnabled = true;\n redactionRules = redact.rules;\n }\n\n const profile = options?.redactionProfile ?? \"local\";\n const resolvedProfile = resolveRedactionProfile(profile);\n\n const userMaxMetadata =\n typeof options?.maxMetadataValueLength === \"number\" &&\n Number.isFinite(options.maxMetadataValueLength) &&\n options.maxMetadataValueLength >= 0\n ? Math.floor(options.maxMetadataValueLength)\n : undefined;\n const userMaxPreview =\n typeof options?.maxPreviewLength === \"number\" &&\n Number.isFinite(options.maxPreviewLength) &&\n options.maxPreviewLength >= 0\n ? Math.floor(options.maxPreviewLength)\n : undefined;\n\n let maxMetadataValueLength = userMaxMetadata ?? DEFAULT_MAX_METADATA_VALUE_LENGTH;\n let maxPreviewLength = userMaxPreview ?? DEFAULT_MAX_PREVIEW_LENGTH;\n\n if (redactEnabled && profile !== \"local\") {\n const capped = applyProfileMetadataCaps(\n maxMetadataValueLength,\n maxPreviewLength,\n resolvedProfile,\n );\n maxMetadataValueLength = capped.maxMetadataValueLength;\n maxPreviewLength = capped.maxPreviewLength;\n }\n\n return {\n redactEnabled,\n redactionRules,\n redactionProfile: profile,\n profileExtraKeys: redactEnabled ? resolvedProfile.extraKeys : [],\n maxMetadataValueLength,\n maxPreviewLength,\n maxEventBytes:\n typeof options?.maxEventBytes === \"number\" &&\n Number.isFinite(options.maxEventBytes) &&\n options.maxEventBytes > 0\n ? Math.floor(options.maxEventBytes)\n : DEFAULT_MAX_EVENT_BYTES,\n };\n}\n\nfunction boundMetadataValue(\n key: string,\n value: unknown,\n opts: TraceSafetyOptions,\n seen: WeakSet<object>,\n depth: number,\n): unknown {\n if (depth > 32) return \"[MaxDepth]\";\n\n if (typeof value === \"bigint\") {\n return `${value.toString()}n`;\n }\n if (typeof value === \"function\") {\n return \"[Function]\";\n }\n if (typeof value === \"symbol\") {\n return \"[Symbol]\";\n }\n if (typeof value === \"number\" && !Number.isFinite(value)) {\n return String(value);\n }\n if (value === undefined) {\n return null;\n }\n\n if (value === null || typeof value !== \"object\") {\n if (typeof value === \"string\") {\n const max = isPreviewKey(key) ? opts.maxPreviewLength : opts.maxMetadataValueLength;\n return truncateString(value, max);\n }\n return value;\n }\n\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n\n if (Array.isArray(value)) {\n const maxItems = 50;\n const out = value\n .slice(0, maxItems)\n .map((item, index) =>\n boundMetadataValue(String(index), item, opts, seen, depth + 1),\n );\n if (value.length > maxItems) {\n out.push(`…(+${value.length - maxItems} more)`);\n }\n return out;\n }\n\n const record = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n try {\n for (const [k, v] of Object.entries(record)) {\n out[k] = boundMetadataValue(k, v, opts, seen, depth + 1);\n }\n } catch {\n return { truncated: true, reason: \"metadataEnumerationFailed\" };\n }\n return out;\n}\n\nfunction redactMetadata(\n metadata: Record<string, unknown>,\n opts: TraceSafetyOptions,\n): Record<string, unknown> {\n if (!opts.redactEnabled) return { ...metadata };\n const redactor = new Redactor({\n rules: opts.redactionRules,\n extraKeys: opts.profileExtraKeys,\n });\n return redactor.redactRecord(metadata);\n}\n\n/** Redacts (when enabled) and truncates metadata values for disk persistence. */\nexport function prepareMetadataForDisk(\n metadata: Record<string, unknown> | StepMetadata,\n opts: TraceSafetyOptions,\n): Record<string, unknown> {\n try {\n const preBounded = boundMetadataValue(\n \"metadata\",\n metadata,\n opts,\n new WeakSet<object>(),\n 0,\n );\n const redacted = redactMetadata(\n isRecord(preBounded) ? preBounded : {},\n opts,\n );\n const bounded = boundMetadataValue(\n \"metadata\",\n redacted,\n opts,\n new WeakSet<object>(),\n 0,\n );\n return isRecord(bounded) ? bounded : {};\n } catch {\n return { truncated: true, reason: \"metadataPreparationFailed\" };\n }\n}\n\nfunction truncateErrorStack(\n event: TraceEvent,\n maxLen: number,\n): TraceEvent {\n if (event.event !== \"run_completed\" && event.event !== \"step_completed\") {\n return event;\n }\n if (!event.error?.stack || typeof event.error.stack !== \"string\") {\n return event;\n }\n return {\n ...event,\n error: {\n ...event.error,\n stack: truncateString(event.error.stack, maxLen),\n },\n };\n}\n\nfunction replaceMetadataWithTruncationMarker(\n event: TraceEvent,\n originalApproxBytes: number,\n): TraceEvent {\n const marker = {\n truncated: true,\n reason: \"maxEventBytes\",\n originalApproxBytes,\n };\n if (event.event === \"run_started\") {\n return { ...event, metadata: marker };\n }\n if (event.event === \"step_started\") {\n return { ...event, metadata: marker };\n }\n return event;\n}\n\nfunction shrinkMetadataLimits(\n opts: TraceSafetyOptions,\n factor: number,\n): TraceSafetyOptions {\n return {\n ...opts,\n maxMetadataValueLength: Math.max(32, Math.floor(opts.maxMetadataValueLength * factor)),\n maxPreviewLength: Math.max(16, Math.floor(opts.maxPreviewLength * factor)),\n };\n}\n\nfunction applyMetadataToEvent(\n event: TraceEvent,\n metadata: Record<string, unknown>,\n): TraceEvent {\n if (event.event === \"run_started\") {\n return { ...event, metadata };\n }\n if (event.event === \"step_started\") {\n return { ...event, metadata: metadata as StepMetadata };\n }\n return event;\n}\n\nfunction eventHasMetadata(event: TraceEvent): boolean {\n return (\n (event.event === \"run_started\" || event.event === \"step_started\") &&\n event.metadata !== undefined\n );\n}\n\nfunction getEventMetadata(event: TraceEvent): Record<string, unknown> | undefined {\n if (event.event === \"run_started\" || event.event === \"step_started\") {\n return event.metadata as Record<string, unknown> | undefined;\n }\n return undefined;\n}\n\n/**\n * Applies redaction, metadata truncation, and final serialized size bounds.\n * Never throws; returns a schema-valid event or a minimally truncated variant.\n */\nexport function prepareTraceEventForDisk(\n event: TraceEvent,\n opts: TraceSafetyOptions,\n): TraceEvent {\n try {\n let working: TraceEvent = { ...event };\n\n const rawMetadata = getEventMetadata(working);\n if (rawMetadata !== undefined) {\n const safe = prepareMetadataForDisk(rawMetadata, opts);\n working = applyMetadataToEvent(working, safe);\n }\n\n let serialized = serializeEvent(working);\n if (serialized === \"\") {\n return working;\n }\n\n let bytes = byteLength(serialized);\n if (bytes <= opts.maxEventBytes) {\n return working;\n }\n\n if (rawMetadata !== undefined) {\n for (const factor of [0.5, 0.25, 0.1]) {\n const tighter = shrinkMetadataLimits(opts, factor);\n const shrunk = prepareMetadataForDisk(rawMetadata, tighter);\n working = applyMetadataToEvent(working, shrunk);\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n }\n\n working = replaceMetadataWithTruncationMarker(working, bytes);\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n }\n\n working = truncateErrorStack(working, Math.min(opts.maxMetadataValueLength, 500));\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n\n if (eventHasMetadata(working)) {\n working = replaceMetadataWithTruncationMarker(working, bytes);\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n\n if (working.event === \"run_started\") {\n const { metadata: _meta, ...rest } = working;\n working = rest;\n } else if (working.event === \"step_started\") {\n const { metadata: _meta, ...rest } = working;\n working = rest;\n }\n }\n\n return working;\n } catch {\n if (event.event === \"run_started\" || event.event === \"step_started\") {\n return applyMetadataToEvent(event, {\n truncated: true,\n reason: \"prepareTraceEventFailed\",\n });\n }\n return event;\n }\n}\n\nfunction safeGet(record: Record<string, unknown>, key: string): unknown {\n try {\n return record[key];\n } catch {\n return undefined;\n }\n}\n\nfunction optionalBoundedString(\n value: unknown,\n _key: string,\n opts: TraceSafetyOptions,\n): string | undefined {\n if (typeof value !== \"string\") return undefined;\n return truncateString(value, opts.maxMetadataValueLength);\n}\n\nfunction requiredBoundedString(\n value: unknown,\n key: string,\n opts: TraceSafetyOptions,\n): string | undefined {\n const out = optionalBoundedString(value, key, opts);\n return out && out.length > 0 ? out : undefined;\n}\n\nfunction preparePersistedSummaryForDisk(\n key: \"input\" | \"output\",\n value: unknown,\n opts: TraceSafetyOptions,\n): unknown {\n try {\n const redactor = new Redactor({\n rules: opts.redactionRules,\n extraKeys: opts.profileExtraKeys,\n });\n const redacted = opts.redactEnabled ? redactor.redactValue(key, value) : value;\n return boundMetadataValue(key, redacted, opts, new WeakSet<object>(), 0);\n } catch {\n return { truncated: true, reason: \"summaryPreparationFailed\" };\n }\n}\n\nfunction preparePersistedErrorForDisk(\n value: unknown,\n opts: TraceSafetyOptions,\n): PersistedInspectError | undefined {\n if (!isRecord(value)) return undefined;\n\n try {\n const redactor = new Redactor({\n rules: opts.redactionRules,\n extraKeys: opts.profileExtraKeys,\n });\n const rawMessage = safeGet(value, \"message\");\n const redactedMessage = opts.redactEnabled\n ? redactor.redactValue(\"message\", rawMessage)\n : rawMessage;\n const boundedMessage = boundMetadataValue(\n \"message\",\n redactedMessage,\n opts,\n new WeakSet<object>(),\n 0,\n );\n const message =\n typeof boundedMessage === \"string\" && boundedMessage.length > 0\n ? boundedMessage\n : \"Unknown error\";\n\n const out: PersistedInspectError = { message };\n const name = optionalBoundedString(safeGet(value, \"name\"), \"name\", opts);\n const code = optionalBoundedString(safeGet(value, \"code\"), \"code\", opts);\n if (name !== undefined) out.name = name;\n if (code !== undefined) out.code = code;\n return out;\n } catch {\n return { message: \"Error preparation failed\" };\n }\n}\n\nfunction prepareTokenUsage(value: unknown): PersistedTokenUsage | undefined {\n if (!isRecord(value)) return undefined;\n const out: PersistedTokenUsage = {};\n for (const key of [\"input\", \"output\", \"total\", \"cached\"] as const) {\n const item = safeGet(value, key);\n if (typeof item === \"number\" && Number.isFinite(item) && item >= 0) {\n out[key] = item;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction prepareTraceContext(\n value: unknown,\n opts: TraceSafetyOptions,\n): PersistedTraceContext | undefined {\n if (!isRecord(value)) return undefined;\n const out: PersistedTraceContext = {};\n const traceId = optionalBoundedString(safeGet(value, \"traceId\"), \"traceId\", opts);\n const spanId = optionalBoundedString(safeGet(value, \"spanId\"), \"spanId\", opts);\n const parentSpanId = optionalBoundedString(\n safeGet(value, \"parentSpanId\"),\n \"parentSpanId\",\n opts,\n );\n if (traceId !== undefined) out.traceId = traceId;\n if (spanId !== undefined) out.spanId = spanId;\n if (parentSpanId !== undefined) out.parentSpanId = parentSpanId;\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction preparePersistedExtensionFieldForDisk(\n key: string,\n value: unknown,\n opts: TraceSafetyOptions,\n): unknown {\n if (isRecord(value)) {\n return prepareMetadataForDisk(value, opts);\n }\n\n const prepared = prepareMetadataForDisk({ [key]: value }, opts);\n return Object.prototype.hasOwnProperty.call(prepared, key)\n ? prepared[key]\n : undefined;\n}\n\nfunction preserveV10ExtensionFields(\n source: Record<string, unknown>,\n candidate: PersistedInspectEvent,\n opts: TraceSafetyOptions,\n): void {\n if (candidate.schemaVersion !== \"1.0\") return;\n\n for (const [key, value] of Object.entries(source)) {\n if (\n KNOWN_PERSISTED_EVENT_FIELDS.has(key) ||\n !isSafeExtensionFieldName(key)\n ) {\n continue;\n }\n\n const prepared = preparePersistedExtensionFieldForDisk(key, value, opts);\n if (prepared !== undefined) {\n candidate[key] = prepared;\n }\n }\n}\n\nfunction serializedPersistedEvent(event: PersistedInspectEvent): string | undefined {\n try {\n return JSON.stringify(event);\n } catch {\n return undefined;\n }\n}\n\nfunction persistedEventByteLength(event: PersistedInspectEvent): number | undefined {\n const serialized = serializedPersistedEvent(event);\n return serialized === undefined ? undefined : byteLength(serialized);\n}\n\nfunction minimalPersistedEvent(\n event: PersistedInspectEvent,\n opts: TraceSafetyOptions,\n originalApproxBytes: number,\n): PersistedInspectEvent {\n return {\n schemaVersion: event.schemaVersion,\n eventId: truncateString(event.eventId, 128),\n runId: truncateString(event.runId, 128),\n kind: event.kind,\n name: truncateString(event.name, 128),\n ...(event.status !== undefined ? { status: event.status } : {}),\n timestamp: truncateString(event.timestamp, 128),\n confidence: event.confidence,\n source: {\n type: event.source.type,\n ...(event.source.name !== undefined\n ? { name: truncateString(event.source.name, 128) }\n : {}),\n ...(event.source.version !== undefined\n ? { version: truncateString(event.source.version, 128) }\n : {}),\n },\n attributes: {\n truncated: true,\n reason: \"maxEventBytes\",\n originalApproxBytes,\n maxEventBytes: opts.maxEventBytes,\n },\n };\n}\n\nfunction tinyPersistedEvent(event: PersistedInspectEvent): PersistedInspectEvent {\n return {\n schemaVersion: event.schemaVersion,\n eventId: truncateString(event.eventId, 32),\n runId: truncateString(event.runId, 32),\n kind: event.kind,\n name: truncateString(event.name, 32),\n timestamp: truncateString(event.timestamp, 32),\n confidence: event.confidence,\n source: { type: event.source.type },\n attributes: { truncated: true, reason: \"maxEventBytes\" },\n };\n}\n\nfunction enforcePersistedEventSize(\n event: PersistedInspectEvent,\n opts: TraceSafetyOptions,\n): PersistedInspectEvent | undefined {\n const bytes = persistedEventByteLength(event);\n if (bytes === undefined) return undefined;\n if (bytes <= opts.maxEventBytes) return event;\n\n const minimal = minimalPersistedEvent(event, opts, bytes);\n const minimalBytes = persistedEventByteLength(minimal);\n if (minimalBytes !== undefined && minimalBytes <= opts.maxEventBytes) {\n return minimal;\n }\n\n const tiny = tinyPersistedEvent(event);\n return isPersistedInspectEvent(tiny) ? tiny : undefined;\n}\n\n/**\n * Prepares persisted inspect events for built-in persistence.\n *\n * The helper is intentionally non-throwing: invalid required fields return\n * `undefined`; supported optional fields are redacted, bounded, JSON-safe, and\n * final serialized-size checked before a writer sees the event.\n */\nexport function preparePersistedInspectEventForWrite(\n value: unknown,\n opts: TraceSafetyOptions = resolveTraceSafetyOptions(),\n): PersistedInspectEvent | undefined {\n try {\n if (!isRecord(value)) return undefined;\n\n const source = safeGet(value, \"source\");\n if (!isRecord(source)) return undefined;\n\n const candidate: PersistedInspectEvent = {\n schemaVersion: safeGet(value, \"schemaVersion\") as PersistedInspectEvent[\"schemaVersion\"],\n eventId: requiredBoundedString(safeGet(value, \"eventId\"), \"eventId\", opts) ?? \"\",\n runId: requiredBoundedString(safeGet(value, \"runId\"), \"runId\", opts) ?? \"\",\n kind: safeGet(value, \"kind\") as PersistedInspectEvent[\"kind\"],\n name: requiredBoundedString(safeGet(value, \"name\"), \"name\", opts) ?? \"\",\n timestamp: requiredBoundedString(safeGet(value, \"timestamp\"), \"timestamp\", opts) ?? \"\",\n confidence: safeGet(value, \"confidence\") as PersistedInspectEvent[\"confidence\"],\n source: {\n type: safeGet(source, \"type\") as PersistedInspectEvent[\"source\"][\"type\"],\n },\n };\n\n const parentId = requiredBoundedString(safeGet(value, \"parentId\"), \"parentId\", opts);\n const status = safeGet(value, \"status\");\n const startedAt = optionalBoundedString(safeGet(value, \"startedAt\"), \"startedAt\", opts);\n const endedAt = optionalBoundedString(safeGet(value, \"endedAt\"), \"endedAt\", opts);\n const durationMs = safeGet(value, \"durationMs\");\n const sourceName = optionalBoundedString(safeGet(source, \"name\"), \"name\", opts);\n const sourceVersion = optionalBoundedString(safeGet(source, \"version\"), \"version\", opts);\n\n if (parentId !== undefined) candidate.parentId = parentId;\n if (\n status === \"running\" ||\n status === \"ok\" ||\n status === \"error\" ||\n status === \"unknown\"\n ) {\n candidate.status = status;\n }\n if (startedAt !== undefined) candidate.startedAt = startedAt;\n if (endedAt !== undefined) candidate.endedAt = endedAt;\n if (\n typeof durationMs === \"number\" &&\n Number.isFinite(durationMs) &&\n durationMs >= 0\n ) {\n candidate.durationMs = durationMs;\n }\n if (sourceName !== undefined) candidate.source.name = sourceName;\n if (sourceVersion !== undefined) candidate.source.version = sourceVersion;\n\n const attributes = safeGet(value, \"attributes\");\n if (isRecord(attributes)) {\n candidate.attributes = prepareMetadataForDisk(attributes, opts);\n }\n\n if (safeGet(value, \"inputSummary\") !== undefined) {\n candidate.inputSummary = preparePersistedSummaryForDisk(\n \"input\",\n safeGet(value, \"inputSummary\"),\n opts,\n );\n }\n if (safeGet(value, \"outputSummary\") !== undefined) {\n candidate.outputSummary = preparePersistedSummaryForDisk(\n \"output\",\n safeGet(value, \"outputSummary\"),\n opts,\n );\n }\n\n const error = preparePersistedErrorForDisk(safeGet(value, \"error\"), opts);\n if (error !== undefined) candidate.error = error;\n\n const tokenUsage = prepareTokenUsage(safeGet(value, \"tokenUsage\"));\n if (tokenUsage !== undefined) candidate.tokenUsage = tokenUsage;\n\n const trace = prepareTraceContext(safeGet(value, \"trace\"), opts);\n if (trace !== undefined) candidate.trace = trace;\n\n preserveV10ExtensionFields(value, candidate, opts);\n\n if (!isPersistedInspectEvent(candidate)) return undefined;\n return enforcePersistedEventSize(candidate, opts);\n } catch {\n return undefined;\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport { extractCorrelationMetadata } from \"./correlation-metadata.js\";\nimport type { ExecutionContext, TraceCorrelationMetadata } from \"./types.js\";\nimport {\n resolveTraceSafetyOptions,\n type TraceSafetyOptions,\n} from \"./trace-event-safety.js\";\n\ntype RuntimeExecutionContext = ExecutionContext & {\n currentStepId?: string;\n currentDepth: number;\n traceSafety: TraceSafetyOptions;\n};\n\nconst storage = new AsyncLocalStorage<RuntimeExecutionContext>();\n\nfunction toPublicContext(ctx: RuntimeExecutionContext): ExecutionContext {\n return {\n runId: ctx.runId,\n runName: ctx.runName,\n traceDir: ctx.traceDir,\n silent: ctx.silent,\n metadata: ctx.metadata,\n };\n}\n\nfunction invoke<T>(fn: () => T | Promise<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n try {\n Promise.resolve(fn()).then(resolve, reject);\n } catch (e) {\n reject(e);\n }\n });\n}\n\n/** Returns the active run context, without internal step fields. */\nexport function getCurrentContext(): ExecutionContext | undefined {\n try {\n const s = storage.getStore();\n if (!s) return undefined;\n return toPublicContext(s);\n } catch {\n return undefined;\n }\n}\n\n/** Active `runId` when inside `runWithContext`, else `undefined`. */\nexport function getCurrentRunId(): string | undefined {\n try {\n return storage.getStore()?.runId;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Correlation metadata for the active run (`correlationId`, `requestId`, `decisionId`, `groupId`).\n * `undefined` outside `inspectRun` / `maybeInspectRun` or when no correlation fields were set.\n */\nexport function getCurrentCorrelationMetadata():\n | TraceCorrelationMetadata\n | undefined {\n try {\n return extractCorrelationMetadata(storage.getStore()?.metadata);\n } catch {\n return undefined;\n }\n}\n\n/** Active `runName` when inside `runWithContext`, else `undefined`. */\nexport function getCurrentRunName(): string | undefined {\n try {\n return storage.getStore()?.runName;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Active step id in this async scope (parent for nested `step()` calls).\n * `undefined` at run root or outside any run.\n */\nexport function getCurrentStepId(): string | undefined {\n try {\n return storage.getStore()?.currentStepId;\n } catch {\n return undefined;\n }\n}\n\n/** Alias of {@link getCurrentStepId} for readability in step instrumentation. */\nexport function getParentStepId(): string | undefined {\n return getCurrentStepId();\n}\n\n/**\n * Nesting depth: `0` at run root, increments by one per nested `runWithStepContext`.\n * Returns `0` outside any run.\n */\nexport function getCurrentDepth(): number {\n try {\n const d = storage.getStore()?.currentDepth;\n return typeof d === \"number\" && Number.isFinite(d) ? d : 0;\n } catch {\n return 0;\n }\n}\n\nexport function hasActiveContext(): boolean {\n try {\n return storage.getStore() !== undefined;\n } catch {\n return false;\n }\n}\n\nexport function getTraceDirFromContext(): string | undefined {\n try {\n return storage.getStore()?.traceDir;\n } catch {\n return undefined;\n }\n}\n\nexport function isSilentContext(): boolean {\n try {\n const s = storage.getStore();\n return s ? s.silent : false;\n } catch {\n return false;\n }\n}\n\n/** Resolved trace safety settings for the active run (redaction + size bounds). */\nexport function getTraceSafetyFromContext(): TraceSafetyOptions | undefined {\n try {\n return storage.getStore()?.traceSafety;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Runs `fn` with a fresh AgentInspect run context (depth 0, no active step).\n * Propagates sync/async results and rejections; does not swallow user errors.\n */\nexport function runWithContext<T>(\n context: ExecutionContext,\n fn: () => Promise<T> | T,\n traceSafety: TraceSafetyOptions = resolveTraceSafetyOptions(),\n): Promise<T> {\n const runtime: RuntimeExecutionContext = {\n runId: context.runId,\n runName: context.runName,\n traceDir: context.traceDir,\n silent: context.silent,\n metadata: context.metadata,\n traceSafety,\n currentDepth: 0,\n };\n\n return new Promise((resolve, reject) => {\n storage.run(runtime, () => {\n try {\n Promise.resolve(fn()).then(resolve, reject);\n } catch (e) {\n reject(e);\n }\n });\n });\n}\n\n/**\n * Runs `fn` with `stepId` as the active step (incremented depth).\n * If no run is active, runs `fn` without altering async context.\n */\nexport function runWithStepContext<T>(\n stepId: string,\n fn: () => Promise<T> | T,\n): Promise<T> {\n let parent: RuntimeExecutionContext | undefined;\n try {\n parent = storage.getStore();\n } catch {\n parent = undefined;\n }\n\n if (!parent) {\n return invoke(fn);\n }\n\n const derived: RuntimeExecutionContext = {\n runId: parent.runId,\n runName: parent.runName,\n traceDir: parent.traceDir,\n silent: parent.silent,\n metadata: parent.metadata,\n traceSafety: parent.traceSafety,\n currentStepId: stepId,\n currentDepth: parent.currentDepth + 1,\n };\n\n return new Promise((resolve, reject) => {\n storage.run(derived, () => {\n try {\n Promise.resolve(fn()).then(resolve, reject);\n } catch (e) {\n reject(e);\n }\n });\n });\n}\n","import chalk from \"chalk\";\n\nimport { isSilentContext } from \"./context.js\";\nimport type { ErrorInfo, RunStatus, StepStatus } from \"./types.js\";\nimport { formatDuration, truncateName } from \"./utils.js\";\n\n/** Two spaces per nesting level in terminal output. */\nexport const TERMINAL_INDENT = \" \";\n\n/** Max display length for names in terminal output. */\nexport const MAX_TERMINAL_NAME_LENGTH = 80;\n\n/** Max nesting depth used for indentation (prevents huge indents). */\nexport const MAX_TERMINAL_DEPTH = 10;\n\nfunction normalizeDepth(depth: number): number {\n if (!Number.isFinite(depth) || depth < 0) {\n return 0;\n }\n return Math.min(Math.floor(depth), MAX_TERMINAL_DEPTH);\n}\n\nfunction safePrint(line = \"\"): void {\n try {\n console.log(line);\n } catch {\n /* never break callers */\n }\n}\n\n/** Indentation string for a nesting depth (capped, never negative). */\nexport function getIndent(depth: number): string {\n return TERMINAL_INDENT.repeat(normalizeDepth(depth));\n}\n\n/** Truncates a display name for terminal use; invalid input becomes `\"unnamed\"`. */\nexport function formatTerminalName(name: string): string {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n return \"unnamed\";\n }\n return truncateName(name, MAX_TERMINAL_NAME_LENGTH);\n}\n\nfunction getStatusIcon(status: StepStatus | RunStatus): string {\n if (status === \"success\") return chalk.green(\"✔\");\n if (status === \"error\") return chalk.red(\"✖\");\n return chalk.yellow(\"⏳\");\n}\n\n/** Renders a single step line (colored); does not consult silent mode. */\nexport function renderStepLine(\n name: string,\n durationMs: number | undefined,\n status: StepStatus,\n depth?: number,\n): string {\n try {\n const nm = formatTerminalName(name);\n const ind = getIndent(depth ?? 0);\n if (status === \"running\" && durationMs === undefined) {\n return `${ind}${chalk.yellow(\"⏳\")} ${nm}`;\n }\n const hasDur =\n durationMs !== undefined && Number.isFinite(durationMs as number);\n const dur = hasDur ? formatDuration(durationMs as number) : undefined;\n if (status === \"running\") {\n return dur !== undefined\n ? `${ind}${chalk.yellow(\"⏳\")} ${nm} (${dur})`\n : `${ind}${chalk.yellow(\"⏳\")} ${nm}`;\n }\n if (!hasDur || dur === undefined) {\n return `${ind}${chalk.yellow(\"⏳\")} ${nm}`;\n }\n if (status === \"success\") {\n return `${ind}${getStatusIcon(\"success\")} ${nm} (${dur})`;\n }\n return `${ind}${getStatusIcon(\"error\")} ${nm} (${dur})`;\n } catch {\n return \"\";\n }\n}\n\n/** Renders an error summary line (no stack in MVP). */\nexport function renderErrorLine(error: ErrorInfo, depth?: number): string {\n try {\n const msg =\n typeof error.message === \"string\" ? error.message : \"\";\n const ind = getIndent((depth ?? 0) + 1);\n return `${ind}Error: ${msg}`;\n } catch {\n return \"\";\n }\n}\n\n/** Plain-text run summary lines (no chalk) for stable testing and CLI reuse. */\nexport function renderRunSummary(\n durationMs: number,\n status: RunStatus,\n traceFilePath?: string,\n): string[] {\n try {\n const dur = Number.isFinite(durationMs)\n ? formatDuration(durationMs)\n : formatDuration(0);\n const head =\n status === \"error\" ? `Failed in ${dur}` : `Completed in ${dur}`;\n const lines = [head];\n if (traceFilePath !== undefined && traceFilePath.trim() !== \"\") {\n lines.push(`Trace: ${traceFilePath}`);\n }\n return lines;\n } catch {\n return [];\n }\n}\n\n/** Prints run header with icon and dim run id. */\nexport function printRunStart(runId: string, name: string): void {\n if (isSilentContext()) return;\n try {\n safePrint(\"\");\n const header = `${chalk.cyan.bold(\"🔍 AgentInspect:\")} ${formatTerminalName(name)} ${chalk.dim(`(${runId})`)}`;\n safePrint(header);\n } catch {\n /* noop */\n }\n}\n\n/** Prints a running step line. */\nexport function printStepStart(name: string, depth = 0): void {\n if (isSilentContext()) return;\n try {\n safePrint(renderStepLine(name, undefined, \"running\", depth));\n } catch {\n /* noop */\n }\n}\n\n/** Prints a completed step line with duration and status icon. */\nexport function printStepComplete(\n name: string,\n durationMs: number,\n status: StepStatus,\n depth = 0,\n): void {\n if (isSilentContext()) return;\n try {\n safePrint(renderStepLine(name, durationMs, status, depth));\n } catch {\n /* noop */\n }\n}\n\n/** Prints a structured error line (message only, no stack). */\nexport function printError(error: ErrorInfo, depth = 0): void {\n if (isSilentContext()) return;\n try {\n safePrint(renderErrorLine(error, depth));\n } catch {\n /* noop */\n }\n}\n\n/** Prints run completion summary and optional trace path. */\nexport function printRunComplete(\n _name: string,\n _runId: string,\n durationMs: number,\n status: RunStatus,\n traceFilePath?: string,\n): void {\n if (isSilentContext()) return;\n try {\n const lines = renderRunSummary(durationMs, status, traceFilePath);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n if (i === 0) {\n const color =\n status === \"error\"\n ? chalk.red\n : status === \"running\"\n ? chalk.yellow\n : chalk.green;\n safePrint(color(line));\n } else {\n safePrint(chalk.dim(line));\n }\n }\n } catch {\n /* noop */\n }\n}\n\n/** Prints which step failed. */\nexport function printFailedAt(stepName: string): void {\n if (isSilentContext()) return;\n try {\n safePrint(`Failed at: ${formatTerminalName(stepName)}`);\n } catch {\n /* noop */\n }\n}\n","import {\n getCurrentContext,\n getCurrentDepth,\n getParentStepId,\n getTraceSafetyFromContext,\n runWithStepContext,\n} from \"./context.js\";\nimport type { StepOptions, StepType, TraceEvent } from \"./types.js\";\nimport { writeTraceEvent } from \"./storage.js\";\nimport { printFailedAt, printError, printStepComplete, printStepStart } from \"./terminal.js\";\nimport { prepareTraceEventForDisk } from \"./trace-event-safety.js\";\nimport { createStepId, formatError, truncateName, warn } from \"./utils.js\";\n\nfunction normalizeStepName(name: unknown): string {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n return \"unnamed-step\";\n }\n return truncateName(name.trim(), 100);\n}\n\nasync function safeInstrumentation(\n label: string,\n op: () => void | Promise<void>,\n): Promise<void> {\n try {\n await Promise.resolve(op());\n } catch (e) {\n warn(`step: ${label}`, e);\n }\n}\n\nasync function stepImpl<T>(\n name: string,\n fn: () => Promise<T> | T,\n options?: StepOptions,\n): Promise<T> {\n if (typeof fn !== \"function\") {\n throw new TypeError(\"step requires `fn` to be a function\");\n }\n\n const stepName = normalizeStepName(name);\n const context = getCurrentContext();\n\n if (!context) {\n warn(\"step() called outside inspectRun(); executing without instrumentation\");\n return Promise.resolve(fn());\n }\n\n const stepId = createStepId();\n const renderDepth = getCurrentDepth();\n const parentId = getParentStepId();\n const stepType: StepType = options?.type ?? \"logic\";\n const metadata = options?.metadata;\n const traceSafety = getTraceSafetyFromContext();\n const startTime = Date.now();\n\n await safeInstrumentation(\"writeTraceEvent(step_started)\", async () => {\n const started: TraceEvent = {\n schemaVersion: \"0.1\",\n event: \"step_started\",\n timestamp: startTime,\n runId: context.runId,\n stepId,\n ...(typeof parentId === \"string\" && parentId.trim() !== \"\"\n ? { parentId }\n : {}),\n name: stepName,\n type: stepType,\n startTime,\n ...(metadata !== undefined ? { metadata } : {}),\n };\n const safe =\n traceSafety !== undefined\n ? prepareTraceEventForDisk(started, traceSafety)\n : started;\n await writeTraceEvent(safe, context.traceDir);\n });\n\n await safeInstrumentation(\"printStepStart\", () => {\n printStepStart(stepName, renderDepth);\n });\n\n let result: T;\n try {\n result = await runWithStepContext(stepId, async () => {\n return await Promise.resolve(fn());\n });\n } catch (userError) {\n const endTime = Date.now();\n const durationMs = endTime - startTime;\n const formatted = formatError(userError);\n\n await safeInstrumentation(\"writeTraceEvent(step_completed error)\", async () => {\n const completed: TraceEvent = {\n schemaVersion: \"0.1\",\n event: \"step_completed\",\n timestamp: endTime,\n runId: context.runId,\n stepId,\n status: \"error\",\n endTime,\n durationMs,\n error: formatted,\n };\n const safe =\n traceSafety !== undefined\n ? prepareTraceEventForDisk(completed, traceSafety)\n : completed;\n await writeTraceEvent(safe, context.traceDir);\n });\n\n await safeInstrumentation(\"printStepComplete(error)\", () => {\n printStepComplete(stepName, durationMs, \"error\", renderDepth);\n });\n await safeInstrumentation(\"printError\", () => {\n printError(formatted, renderDepth);\n });\n await safeInstrumentation(\"printFailedAt\", () => {\n printFailedAt(stepName);\n });\n\n throw userError;\n }\n\n const endTime = Date.now();\n const durationMs = endTime - startTime;\n\n await safeInstrumentation(\"writeTraceEvent(step_completed success)\", async () => {\n const completed: TraceEvent = {\n schemaVersion: \"0.1\",\n event: \"step_completed\",\n timestamp: endTime,\n runId: context.runId,\n stepId,\n status: \"success\",\n endTime,\n durationMs,\n };\n const safe =\n traceSafety !== undefined\n ? prepareTraceEventForDisk(completed, traceSafety)\n : completed;\n await writeTraceEvent(safe, context.traceDir);\n });\n\n await safeInstrumentation(\"printStepComplete(success)\", () => {\n printStepComplete(stepName, durationMs, \"success\", renderDepth);\n });\n\n return result;\n}\n\n/**\n * Stable v1.0 API for instrumenting a named step inside an AgentInspect run.\n *\n * Callable step tracer plus {@link step.llm} and {@link step.tool} shortcuts.\n */\nexport type StepFunction = {\n <T>(name: string, fn: () => Promise<T> | T, options?: StepOptions): Promise<T>;\n llm: <T>(model: string, fn: () => Promise<T> | T) => Promise<T>;\n tool: <T>(toolName: string, fn: () => Promise<T> | T) => Promise<T>;\n};\n\nasync function stepLlm<T>(model: string, fn: () => Promise<T> | T): Promise<T> {\n const modelName =\n typeof model === \"string\" && model.trim() !== \"\"\n ? model.trim()\n : \"unknown-model\";\n return stepImpl<T>(`llm:${modelName}`, fn, {\n type: \"llm\",\n metadata: { model: modelName },\n });\n}\n\nasync function stepTool<T>(\n toolName: string,\n fn: () => Promise<T> | T,\n): Promise<T> {\n const normalized =\n typeof toolName === \"string\" && toolName.trim() !== \"\"\n ? toolName.trim()\n : \"unknown-tool\";\n return stepImpl<T>(`tool:${normalized}`, fn, {\n type: \"tool\",\n metadata: { toolName: normalized },\n });\n}\n\n/**\n * Traces a named unit of work inside `inspectRun` (`step_started` / `step_completed`, optional terminal).\n * Outside a run, executes `fn` with a warn only. Preserves return values and rethrows user errors unchanged.\n *\n * - `step.llm(model, fn)` — `type: \"llm\"`, `metadata.model` (no SDK calls or token counting).\n * - `step.tool(toolName, fn)` — `type: \"tool\"`, `metadata.toolName` (no framework interception).\n */\nexport const step = Object.assign(stepImpl, {\n llm: stepLlm,\n tool: stepTool,\n}) as StepFunction;\n","import { step } from \"agent-inspect\";\n\nimport { hashServerUrl, summarizeMcpValue } from \"./summarize.js\";\nimport type {\n McpClientLike,\n McpClientTracerOptions,\n McpTraceMetadata,\n} from \"./types.js\";\n\nlet toolCallCounter = 0;\n\nfunction nextToolCallId(prefix?: string): string {\n toolCallCounter += 1;\n const base = prefix?.trim() || \"mcp\";\n return `${base}-${toolCallCounter}`;\n}\n\nfunction baseMetadata(\n options: McpClientTracerOptions,\n overrides: Partial<McpTraceMetadata> = {},\n): Record<string, unknown> {\n const metadata: McpTraceMetadata = {\n source: { type: \"mcp-client\" },\n ...(options.serverName ? { mcpServerName: options.serverName } : {}),\n ...(options.serverUrl\n ? { mcpServerUrlHash: hashServerUrl(options.serverUrl) }\n : {}),\n ...(options.sessionId ? { sessionId: options.sessionId } : {}),\n ...overrides,\n };\n return { ...(options.metadata ?? {}), ...metadata };\n}\n\n/**\n * Wraps an MCP client so tools/list and tools/call emit local tool steps.\n * Telemetry only — does not proxy network behavior beyond the wrapped client.\n */\nexport function wrapMcpClient<T extends McpClientLike>(\n client: T,\n options: McpClientTracerOptions = {},\n): T {\n const maxSummaryLength = options.maxSummaryLength ?? 240;\n const wrapped = { ...client } as T;\n\n if (typeof client.listTools === \"function\") {\n const listTools = client.listTools.bind(client);\n wrapped.listTools = async (params?: unknown) =>\n step(\n \"mcp:tools/list\",\n async () => {\n const result = await listTools(params);\n return result;\n },\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: \"tools/list\",\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n }),\n },\n );\n }\n\n const callTool = client.callTool.bind(client);\n wrapped.callTool = async (params) =>\n step(\n `mcp:${params.name}`,\n async () => callTool(params),\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: params.name,\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n argumentSummary: summarizeMcpValue(\n params.arguments ?? {},\n maxSummaryLength,\n ),\n }),\n },\n );\n\n return wrapped;\n}\n\n/** @internal resets tool call ids for deterministic tests */\nexport function resetMcpToolCallIdsForTests(): void {\n toolCallCounter = 0;\n}\n"]}
package/dist/index.mjs CHANGED
@@ -390,6 +390,9 @@ function validateEvent(event) {
390
390
  case "step_completed": {
391
391
  return nonEmptyString(event.runId) && nonEmptyString(event.stepId) && (event.status === "success" || event.status === "error") && finiteNumber(event.endTime) && finiteNumber(event.durationMs) && optionalErrorInfo(event.error);
392
392
  }
393
+ case "outcome_observed": {
394
+ return nonEmptyString(event.runId) && nonEmptyString(event.outcomeId) && nonEmptyString(event.name) && nonEmptyString(event.expectation) && (event.status === "passed" || event.status === "failed" || event.status === "unknown" || event.status === "skipped") && finiteNumber(event.observedAt);
395
+ }
393
396
  default:
394
397
  return false;
395
398
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/summarize.ts","../../core/src/logs/redactor.ts","../../core/src/redaction-profiles.ts","../../core/src/types.ts","../../core/src/utils/duration.ts","../../core/src/utils.ts","../../core/src/storage.ts","../../core/src/trace-event-safety.ts","../../core/src/context.ts","../../core/src/terminal.ts","../../core/src/step.ts","../src/wrap.ts"],"names":["formatDuration","isRecord","out","AsyncLocalStorage","endTime","durationMs"],"mappings":"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","file":"index.mjs","sourcesContent":["const DEFAULT_MAX_SUMMARY_LENGTH = 240;\n\nexport function summarizeMcpValue(\n value: unknown,\n maxLength = DEFAULT_MAX_SUMMARY_LENGTH,\n): string {\n let text: string;\n try {\n if (typeof value === \"string\") {\n text = value;\n } else {\n text = JSON.stringify(value);\n }\n } catch {\n text = String(value);\n }\n if (text.length <= maxLength) return text;\n return `${text.slice(0, Math.max(0, maxLength - 3))}...`;\n}\n\nexport function hashServerUrl(url: string): string {\n let hash = 0;\n for (let i = 0; i < url.length; i += 1) {\n hash = (hash * 31 + url.charCodeAt(i)) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n","import crypto from \"node:crypto\";\n\nimport type { RedactionRule } from \"../types/log-config.js\";\n\nexport const DEFAULT_REDACT_KEYS = [\n \"authorization\",\n \"cookie\",\n \"token\",\n \"apiKey\",\n \"password\",\n \"secret\",\n \"email\",\n] as const;\n\nexport interface RedactorOptions {\n rules?: RedactionRule[];\n /** Additional exact keys (case-insensitive) to redact in addition to defaults. */\n extraKeys?: readonly string[];\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction toKey(s: string): string {\n return s.toLowerCase();\n}\n\nfunction stableHash(value: string): string {\n const h = crypto.createHash(\"sha256\").update(value, \"utf8\").digest(\"hex\");\n return h.slice(0, 8);\n}\n\ntype CompiledRule =\n | { key: string; strategy: \"full\" }\n | { key: string; strategy: \"prefix\"; keep: number }\n | { key: string; strategy: \"hash\" };\n\nfunction compileRules(\n rules?: RedactionRule[],\n extraKeys?: readonly string[],\n): CompiledRule[] {\n const out = new Map<string, CompiledRule>();\n\n const set = (r: CompiledRule) => {\n const k = toKey(r.key);\n out.set(k, { ...r, key: k } as CompiledRule);\n };\n\n for (const k of DEFAULT_REDACT_KEYS) {\n set({ key: k, strategy: \"full\" });\n }\n\n for (const k of extraKeys ?? []) {\n if (typeof k === \"string\" && k.length > 0) {\n set({ key: k, strategy: \"full\" });\n }\n }\n\n for (const r of rules ?? []) {\n if (typeof r === \"string\") {\n set({ key: r, strategy: \"full\" });\n continue;\n }\n const key = r.key;\n if (r.strategy === \"full\") set({ key, strategy: \"full\" });\n if (r.strategy === \"hash\") set({ key, strategy: \"hash\" });\n if (r.strategy === \"prefix\") {\n set({ key, strategy: \"prefix\", keep: typeof r.keep === \"number\" ? r.keep : 8 });\n }\n }\n\n return [...out.values()];\n}\n\nexport class Redactor {\n readonly #rules: CompiledRule[];\n\n constructor(options?: RedactorOptions) {\n this.#rules = compileRules(options?.rules, options?.extraKeys);\n }\n\n redactValue(key: string, value: unknown): unknown {\n const k = toKey(key);\n const rule = this.#rules.find((r) => r.key === k);\n if (!rule) {\n return this.#redactNested(value);\n }\n\n if (rule.strategy === \"full\") return \"[REDACTED]\";\n const asString =\n typeof value === \"string\"\n ? value\n : typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\"\n ? String(value)\n : undefined;\n\n if (rule.strategy === \"prefix\") {\n if (asString === undefined) return \"[REDACTED]\";\n const keep = Math.max(0, Math.floor(rule.keep));\n return asString.length <= keep ? `${asString}…` : `${asString.slice(0, keep)}…`;\n }\n\n if (rule.strategy === \"hash\") {\n if (asString === undefined) return \"[HASH:unknown]\";\n return `[HASH:${stableHash(asString)}]`;\n }\n\n return this.#redactNested(value);\n }\n\n redactRecord(record: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(record)) {\n out[k] = this.redactValue(k, v);\n }\n return out;\n }\n\n #redactNested(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((v) => this.#redactNested(v));\n }\n if (isRecord(value)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n out[k] = this.redactValue(k, v);\n }\n return out;\n }\n return value;\n }\n}\n\n","import type { RedactionProfile } from \"./types.js\";\n\n/** Extra keys redacted under the `share` profile (in addition to {@link DEFAULT_REDACT_KEYS}). */\nexport const SHARE_PROFILE_EXTRA_KEYS = [\n \"userEmail\",\n \"customerEmail\",\n \"phone\",\n \"phoneNumber\",\n \"address\",\n \"ip\",\n \"ipAddress\",\n \"sessionId\",\n \"requestId\",\n \"correlationId\",\n \"decisionId\",\n \"groupId\",\n \"customerId\",\n \"userId\",\n \"accountId\",\n \"tenantId\",\n \"orgId\",\n \"organizationId\",\n \"traceId\",\n \"spanId\",\n \"parentSpanId\",\n] as const;\n\n/** Extra keys redacted under the `strict` profile (in addition to share keys). */\nexport const STRICT_PROFILE_EXTRA_KEYS = [\n \"prompt\",\n \"completion\",\n \"input\",\n \"output\",\n \"inputPreview\",\n \"outputPreview\",\n \"message\",\n \"messages\",\n \"transcript\",\n \"context\",\n \"document\",\n \"documents\",\n \"chunk\",\n \"chunks\",\n \"retrieval\",\n \"query\",\n] as const;\n\nexport interface ResolvedRedactionProfile {\n profile: RedactionProfile;\n extraKeys: readonly string[];\n maxMetadataValueLengthCap?: number;\n maxPreviewLengthCap?: number;\n}\n\n/** Resolves named profile behavior (keys + metadata string caps). */\nexport function resolveRedactionProfile(\n profile: RedactionProfile = \"local\",\n): ResolvedRedactionProfile {\n switch (profile) {\n case \"local\":\n return { profile: \"local\", extraKeys: [] };\n case \"share\":\n return {\n profile: \"share\",\n extraKeys: SHARE_PROFILE_EXTRA_KEYS,\n maxMetadataValueLengthCap: 500,\n maxPreviewLengthCap: 200,\n };\n case \"strict\":\n return {\n profile: \"strict\",\n extraKeys: [...SHARE_PROFILE_EXTRA_KEYS, ...STRICT_PROFILE_EXTRA_KEYS],\n maxMetadataValueLengthCap: 200,\n maxPreviewLengthCap: 80,\n };\n default:\n return { profile: \"local\", extraKeys: [] };\n }\n}\n\nfunction isPreviewKey(key: string): boolean {\n return key.toLowerCase().includes(\"preview\");\n}\n\n/**\n * Applies profile metadata string caps. User-provided lower limits are preserved.\n */\nexport function applyProfileMetadataCaps(\n maxMetadataValueLength: number,\n maxPreviewLength: number,\n resolved: ResolvedRedactionProfile,\n): { maxMetadataValueLength: number; maxPreviewLength: number } {\n let meta = maxMetadataValueLength;\n let preview = maxPreviewLength;\n\n if (resolved.maxMetadataValueLengthCap !== undefined) {\n meta = Math.min(meta, resolved.maxMetadataValueLengthCap);\n }\n if (resolved.maxPreviewLengthCap !== undefined) {\n preview = Math.min(preview, resolved.maxPreviewLengthCap);\n }\n\n return { maxMetadataValueLength: meta, maxPreviewLength: preview };\n}\n\nexport function truncateStringForProfile(\n value: string,\n key: string,\n maxMetadataValueLength: number,\n maxPreviewLength: number,\n): string {\n const max = isPreviewKey(key) ? maxPreviewLength : maxMetadataValueLength;\n if (max <= 0) return \"…\";\n if (value.length <= max) return value;\n return `${value.slice(0, max)}…`;\n}\n","import type { RedactionRule } from \"./types/log-config.js\";\n\n/**\n * Discriminator for what kind of work a {@link Step} represents.\n * `\"decision\"` captures agent branching/choices; other values cover runs, LLM calls, tools, and user-defined steps.\n */\nexport type StepType =\n | \"run\"\n | \"llm\"\n | \"tool\"\n | \"decision\"\n | \"logic\"\n | \"state\"\n | \"custom\";\n\n/** Lifecycle state of a single {@link Step}. */\nexport type StepStatus = \"running\" | \"success\" | \"error\";\n\n/** Lifecycle state of an entire {@link Run}. */\nexport type RunStatus = \"running\" | \"success\" | \"error\";\n\n/** Structured error attached to a run or step when status is `\"error\"`. */\nexport interface ErrorInfo {\n message: string;\n stack?: string;\n}\n\n/**\n * Optional token counts for a step (e.g. LLM usage).\n * Reserved for future roadmap; MVP does not compute or persist token usage.\n */\nexport interface TokenMetadata {\n input?: number;\n output?: number;\n total?: number;\n cached?: number;\n}\n\n/** Arbitrary structured fields for a step; safe extensions use string keys. */\nexport interface StepMetadata {\n model?: string;\n toolName?: string;\n tokens?: TokenMetadata;\n retryCount?: number;\n [key: string]: unknown;\n}\n\n/**\n * One traced agent run (root of an execution tree).\n * MVP intentionally omits `input` / `output` on the run to limit PII, secrets, and serialization risk.\n */\nexport interface Run {\n id: string;\n name: string;\n status: RunStatus;\n startTime: number;\n endTime?: number;\n durationMs?: number;\n error?: ErrorInfo;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * One node in the execution tree under a {@link Run}.\n * MVP intentionally omits `input` / `output`; capture/redaction may come in a later version.\n */\nexport interface Step {\n id: string;\n runId: string;\n parentId?: string;\n name: string;\n type: StepType;\n status: StepStatus;\n startTime: number;\n endTime?: number;\n durationMs?: number;\n error?: ErrorInfo;\n metadata?: StepMetadata;\n}\n\n/** Version of the JSONL trace line schema consumed by AgentInspect tooling. */\nexport type TraceSchemaVersion = \"0.1\";\n\n/**\n * Status for lightweight trace metadata extraction.\n * `\"unknown\"` means the file contained valid events but a run status could not be determined safely.\n */\nexport type TraceMetadataStatus = \"success\" | \"error\" | \"running\" | \"unknown\";\n\nexport interface TraceMetadata {\n runId: string;\n name?: string;\n status: TraceMetadataStatus;\n startedAt?: number;\n endedAt?: number;\n durationMs?: number;\n eventCount: number;\n filePath: string;\n fileSize: number;\n createdAt: Date;\n}\n\nexport interface RunSummary {\n runId: string;\n name?: string;\n status: TraceMetadataStatus;\n durationMs?: number;\n totalSteps: number;\n llmSteps: number;\n toolSteps: number;\n logicSteps: number;\n errorSteps: number;\n maxDepth: number;\n longestStep?: {\n name: string;\n durationMs: number;\n type: string;\n };\n totalTokens?: {\n input: number;\n output: number;\n /** Present only when every token-bearing step has a supplied or derivable total. */\n total?: number;\n /** Sum of supplied cached counts; cached is not added to total. */\n cached?: number;\n };\n}\n\n/** Fields shared by every persisted trace event line. */\nexport interface TraceEventBase {\n schemaVersion: TraceSchemaVersion;\n event: string;\n timestamp: number;\n}\n\n/** Emitted when a run begins. */\nexport interface RunStartedEvent extends TraceEventBase {\n event: \"run_started\";\n runId: string;\n name: string;\n startTime: number;\n metadata?: Record<string, unknown>;\n}\n\n/** Emitted when a run finishes successfully or with an error. */\nexport interface RunCompletedEvent extends TraceEventBase {\n event: \"run_completed\";\n runId: string;\n status: \"success\" | \"error\";\n endTime: number;\n durationMs: number;\n error?: ErrorInfo;\n}\n\n/** Emitted when a step begins (including nested steps under `parentId`). */\nexport interface StepStartedEvent extends TraceEventBase {\n event: \"step_started\";\n runId: string;\n stepId: string;\n parentId?: string;\n name: string;\n type: StepType;\n startTime: number;\n metadata?: StepMetadata;\n}\n\n/**\n * Emitted when a step finishes (success or failure).\n * Failures use `status: \"error\"` and optional {@link ErrorInfo}; there is no separate `step_failed` event in MVP.\n */\nexport interface StepCompletedEvent extends TraceEventBase {\n event: \"step_completed\";\n runId: string;\n stepId: string;\n status: \"success\" | \"error\";\n endTime: number;\n durationMs: number;\n error?: ErrorInfo;\n}\n\n/** Discriminated union of all MVP trace events written as JSONL lines. */\nexport type TraceEvent =\n | RunStartedEvent\n | RunCompletedEvent\n | StepStartedEvent\n | StepCompletedEvent;\n\n/** Named redaction presets for trace writing and share-safe exports (v1.3.0+). */\nexport type RedactionProfile = \"local\" | \"share\" | \"strict\";\n\n/** Optional correlation fields for grouping and cross-run tracing (v1.3.0+). */\nexport interface TraceCorrelationMetadata {\n correlationId?: string;\n requestId?: string;\n decisionId?: string;\n groupId?: string;\n}\n\n/** Options for `inspectRun()` and `maybeInspectRun()`. */\nexport interface InspectRunOptions extends TraceCorrelationMetadata {\n traceDir?: string;\n silent?: boolean;\n metadata?: Record<string, unknown>;\n /**\n * When `false`, runs `fn` with no trace file, no execution context, and no terminal output.\n * Omitted or `true` preserves default tracing behavior.\n */\n enabled?: boolean;\n /**\n * Redact sensitive metadata keys before writing JSONL. Default `true` (conservative keys).\n * Pass `false` to persist metadata as-is (explicit opt-out).\n */\n redact?: boolean | { rules?: RedactionRule[] };\n /**\n * Redaction preset for trace metadata. Default `local` (same keys as default redaction).\n * `share` and `strict` add extra key-based redaction and tighter string bounds.\n * Ignored when `redact: false`.\n */\n redactionProfile?: RedactionProfile;\n /** Max UTF-8 bytes for a serialized trace event line. Default 65536. */\n maxEventBytes?: number;\n /** Max length for string metadata values (non-preview keys). Default 2000. */\n maxMetadataValueLength?: number;\n /** Max length for preview-like metadata keys (contains `preview`). Default 500. */\n maxPreviewLength?: number;\n}\n\n/** Options passed when opening a logical step (implemented in a later step). */\nexport interface StepOptions {\n type?: StepType;\n metadata?: StepMetadata;\n}\n\n/** Options for `observe()` — same surface as {@link InspectRunOptions} in MVP. */\nexport type ObserveOptions = InspectRunOptions;\n\n/**\n * Resolved settings for the active run while tracing is enabled.\n * Populated by runtime code in a later step; defined here for `context.ts`.\n */\nexport interface ExecutionContext {\n runId: string;\n runName: string;\n traceDir: string;\n silent: boolean;\n metadata?: Record<string, unknown>;\n}\n\n/** Stack position of the step currently executing (used by future context tracking). */\nexport interface ActiveStepContext {\n stepId: string;\n parentId?: string;\n depth: number;\n}\n\nconst STEP_TYPES: readonly StepType[] = [\n \"run\",\n \"llm\",\n \"tool\",\n \"decision\",\n \"logic\",\n \"state\",\n \"custom\",\n] as const;\n\nconst STEP_STATUSES: readonly StepStatus[] = [\n \"running\",\n \"success\",\n \"error\",\n] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Returns true if `value` is one of the MVP {@link StepType} literals. */\nexport function isStepType(value: unknown): value is StepType {\n return (\n typeof value === \"string\" &&\n (STEP_TYPES as readonly string[]).includes(value)\n );\n}\n\n/** Returns true if `value` is one of the MVP {@link StepStatus} literals. */\nexport function isStepStatus(value: unknown): value is StepStatus {\n return (\n typeof value === \"string\" &&\n (STEP_STATUSES as readonly string[]).includes(value)\n );\n}\n\n/**\n * Narrowing guard for a {@link TraceEvent} object with required MVP fields.\n * Does not deeply validate optional `metadata` shapes.\n */\nexport function isTraceEvent(value: unknown): value is TraceEvent {\n if (!isRecord(value)) return false;\n if (value.schemaVersion !== \"0.1\") return false;\n if (typeof value.timestamp !== \"number\") return false;\n if (typeof value.event !== \"string\") return false;\n\n switch (value.event) {\n case \"run_started\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.name === \"string\" &&\n typeof value.startTime === \"number\"\n );\n }\n case \"run_completed\": {\n return (\n typeof value.runId === \"string\" &&\n (value.status === \"success\" || value.status === \"error\") &&\n typeof value.endTime === \"number\" &&\n typeof value.durationMs === \"number\"\n );\n }\n case \"step_started\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.stepId === \"string\" &&\n typeof value.name === \"string\" &&\n isStepType(value.type) &&\n typeof value.startTime === \"number\"\n );\n }\n case \"step_completed\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.stepId === \"string\" &&\n (value.status === \"success\" || value.status === \"error\") &&\n typeof value.endTime === \"number\" &&\n typeof value.durationMs === \"number\"\n );\n }\n default:\n return false;\n }\n}\n","/**\n * v0.2 shared duration utilities.\n *\n * `parseDuration` is used for filters such as \"since\" / \"older-than\".\n * `formatDuration` is used for compact display in CLI and summaries.\n */\n\nexport function parseDuration(duration: string): number {\n const raw = typeof duration === \"string\" ? duration.trim() : \"\";\n const match = raw.match(/^(\\d+)(ms|[smhd])$/);\n if (!match) {\n throw new Error(\n `Invalid duration format: ${duration}. Use a positive integer followed by ms, s, m, h, or d (e.g. 500ms, 30s, 5m, 2h, 7d).`,\n );\n }\n\n const amount = Number.parseInt(match[1], 10);\n const unit = match[2];\n\n if (!Number.isFinite(amount) || amount <= 0) {\n throw new Error(\n `Invalid duration amount: ${duration}. Amount must be a positive integer.`,\n );\n }\n\n switch (unit) {\n case \"ms\":\n return amount;\n case \"s\":\n return amount * 1000;\n case \"m\":\n return amount * 60 * 1000;\n case \"h\":\n return amount * 60 * 60 * 1000;\n case \"d\":\n return amount * 24 * 60 * 60 * 1000;\n default: {\n // Should be unreachable due to regex.\n throw new Error(`Unknown duration unit: ${unit}`);\n }\n }\n}\n\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms)) {\n return \"0ms\";\n }\n if (ms < 0) {\n throw new Error(`formatDuration: ms must be non-negative (got ${ms})`);\n }\n if (ms < 1000) {\n return `${Math.floor(ms)}ms`;\n }\n if (ms < 60_000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n if (ms < 3_600_000) {\n return `${(ms / 60_000).toFixed(1)}m`;\n }\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\n","import { mkdir } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nimport { nanoid } from \"nanoid\";\n\nimport type { ErrorInfo } from \"./types.js\";\nimport { formatDuration as formatDurationV2 } from \"./utils/duration.js\";\n\n/** Default folder under the user home for AgentInspect data. */\nexport const DEFAULT_TRACE_DIR_NAME = \".agent-inspect\";\n\n/** Subfolder where JSONL run traces are stored. */\nexport const RUNS_DIR_NAME = \"runs\";\n\n/** Writable trace root when the default home path cannot be used. */\nexport const FALLBACK_TRACE_DIR = path.join(\n os.tmpdir(),\n \"agent-inspect\",\n RUNS_DIR_NAME,\n);\n\n/** Maximum display length for run/step names before truncation. */\nexport const MAX_NAME_LENGTH = 100;\n\n/** Returns `run_` + a 10-character nanoid segment. */\nexport function createRunId(): string {\n return `run_${nanoid(10)}`;\n}\n\n/** Returns `step_` + a 10-character nanoid segment. */\nexport function createStepId(): string {\n return `step_${nanoid(10)}`;\n}\n\n/** Formats a duration for CLI display (v0.2 rules). */\nexport function formatDuration(ms: number): string {\n return formatDurationV2(ms);\n}\n\n/**\n * Formats a Unix timestamp (ms) as local `YYYY-MM-DD HH:mm:ss`.\n * Invalid values yield `\"Invalid date\"` (no throw).\n */\nexport function formatTimestamp(timestamp: number): string {\n if (!Number.isFinite(timestamp)) {\n return \"Invalid date\";\n }\n const d = new Date(timestamp);\n if (Number.isNaN(d.getTime())) {\n return \"Invalid date\";\n }\n const y = d.getFullYear();\n const mo = String(d.getMonth() + 1).padStart(2, \"0\");\n const day = String(d.getDate()).padStart(2, \"0\");\n const h = String(d.getHours()).padStart(2, \"0\");\n const min = String(d.getMinutes()).padStart(2, \"0\");\n const s = String(d.getSeconds()).padStart(2, \"0\");\n return `${y}-${mo}-${day} ${h}:${min}:${s}`;\n}\n\n/**\n * Default directory for trace files: `~/DEFAULT_TRACE_DIR_NAME/RUNS_DIR_NAME`.\n * Falls back to {@link FALLBACK_TRACE_DIR} when home cannot be resolved.\n */\nexport function getDefaultTraceDir(): string {\n const envDir = process.env.AGENT_INSPECT_TRACE_DIR;\n if (typeof envDir === \"string\" && envDir.trim() !== \"\") {\n return envDir.trim();\n }\n try {\n const home = os.homedir();\n if (typeof home !== \"string\" || home.trim() === \"\") {\n return FALLBACK_TRACE_DIR;\n }\n return path.join(home, DEFAULT_TRACE_DIR_NAME, RUNS_DIR_NAME);\n } catch {\n return FALLBACK_TRACE_DIR;\n }\n}\n\n/**\n * Full path to the JSONL trace file for a run.\n * `runId` is passed through `path.basename` to avoid traversal; empty ids become `run_unknown`.\n */\nexport function getTraceFilePath(runId: string, traceDir?: string): string {\n const baseDir = traceDir ?? getDefaultTraceDir();\n let safeId =\n typeof runId === \"string\" && runId.trim() !== \"\" ? runId.trim() : \"run_unknown\";\n safeId = path.basename(safeId);\n if (safeId === \"\" || safeId === \".\" || safeId === \"..\") {\n safeId = \"run_unknown\";\n }\n return path.join(baseDir, `${safeId}.jsonl`);\n}\n\n/**\n * Ensures a trace directory exists (recursive). Tries {@link FALLBACK_TRACE_DIR} on failure.\n * Returns the directory path that callers should prefer: primary, fallback, or original if both mkdir attempts fail.\n * Emits concise `[AgentInspect]` warnings on failure; never throws.\n */\nexport async function ensureTraceDir(traceDir: string): Promise<string> {\n const primary = path.resolve(traceDir);\n try {\n await mkdir(primary, { recursive: true });\n return primary;\n } catch {\n warn(`Failed to create trace directory: ${primary}`);\n const fallback = path.resolve(FALLBACK_TRACE_DIR);\n try {\n await mkdir(fallback, { recursive: true });\n return fallback;\n } catch {\n warn(`Failed to create fallback trace directory: ${fallback}`);\n return primary;\n }\n }\n}\n\n/**\n * Normalizes any thrown/caught value into {@link ErrorInfo}.\n * Never throws (circular structures and non-JSON values fall back to a generic message).\n */\nexport function formatError(error: unknown): ErrorInfo {\n if (error instanceof Error) {\n const out: ErrorInfo = { message: error.message };\n if (typeof error.stack === \"string\" && error.stack.length > 0) {\n out.stack = error.stack;\n }\n return out;\n }\n if (typeof error === \"string\") {\n return { message: error };\n }\n if (error === null) {\n return { message: \"Unknown error: null\" };\n }\n if (error === undefined) {\n return { message: \"Unknown error: undefined\" };\n }\n if (\n typeof error === \"number\" ||\n typeof error === \"boolean\" ||\n typeof error === \"bigint\"\n ) {\n return { message: String(error) };\n }\n if (typeof error === \"object\") {\n try {\n return { message: JSON.stringify(error) };\n } catch {\n return { message: \"Unknown error\" };\n }\n }\n return { message: \"Unknown error\" };\n}\n\n/**\n * Truncates a display name to `maxLength`, appending `\"...\"` when shortened.\n * Empty or non-string input becomes `\"unnamed\"`.\n */\nexport function truncateName(name: string, maxLength = MAX_NAME_LENGTH): string {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n return \"unnamed\";\n }\n const trimmed = name.trim();\n if (trimmed.length <= maxLength) {\n return trimmed;\n }\n const ellipsis = \"...\";\n const head = Math.max(0, maxLength - ellipsis.length);\n return `${trimmed.slice(0, head)}${ellipsis}`;\n}\n\n/**\n * Instrumentation-only warning to stderr. Not a general-purpose logger.\n * Optional `error` is summarized via {@link formatError} (message only).\n */\nexport function warn(message: string, error?: unknown): void {\n const base = `[AgentInspect] ${message}`;\n if (error === undefined) {\n console.warn(base);\n return;\n }\n console.warn(`${base}: ${formatError(error).message}`);\n}\n","import { appendFile, readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { TraceEvent } from \"./types.js\";\nimport { isStepType } from \"./types.js\";\nimport {\n DEFAULT_MAX_EVENT_BYTES,\n prepareTraceEventForDisk,\n resolveTraceSafetyOptions,\n} from \"./trace-event-safety.js\";\nimport { parseTraceJsonl } from \"./read-trace.js\";\nimport {\n ensureTraceDir,\n FALLBACK_TRACE_DIR,\n getTraceFilePath,\n warn,\n} from \"./utils.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction nonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim() !== \"\";\n}\n\nfunction finiteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction optionalErrorInfo(value: unknown): boolean {\n if (value === undefined) return true;\n if (!isRecord(value)) return false;\n if (typeof value.message !== \"string\") return false;\n if (\"stack\" in value && value.stack !== undefined) {\n if (typeof value.stack !== \"string\") return false;\n }\n return true;\n}\n\n/**\n * Strict MVP validation before writing JSONL. Rejects empty ids, non-finite times, and malformed payloads.\n */\nexport function validateEvent(event: unknown): event is TraceEvent {\n if (!isRecord(event)) return false;\n if (event.schemaVersion !== \"0.1\") return false;\n if (!finiteNumber(event.timestamp)) return false;\n if (typeof event.event !== \"string\") return false;\n\n switch (event.event) {\n case \"run_started\": {\n if (\n !nonEmptyString(event.runId) ||\n !nonEmptyString(event.name) ||\n !finiteNumber(event.startTime)\n ) {\n return false;\n }\n if (event.metadata !== undefined && !isRecord(event.metadata)) {\n return false;\n }\n return true;\n }\n case \"run_completed\": {\n return (\n nonEmptyString(event.runId) &&\n (event.status === \"success\" || event.status === \"error\") &&\n finiteNumber(event.endTime) &&\n finiteNumber(event.durationMs) &&\n optionalErrorInfo(event.error)\n );\n }\n case \"step_started\": {\n if (\n !nonEmptyString(event.runId) ||\n !nonEmptyString(event.stepId) ||\n !nonEmptyString(event.name) ||\n !isStepType(event.type) ||\n !finiteNumber(event.startTime)\n ) {\n return false;\n }\n if (event.parentId !== undefined && typeof event.parentId !== \"string\") {\n return false;\n }\n if (event.metadata !== undefined && !isRecord(event.metadata)) {\n return false;\n }\n return true;\n }\n case \"step_completed\": {\n return (\n nonEmptyString(event.runId) &&\n nonEmptyString(event.stepId) &&\n (event.status === \"success\" || event.status === \"error\") &&\n finiteNumber(event.endTime) &&\n finiteNumber(event.durationMs) &&\n optionalErrorInfo(event.error)\n );\n }\n default:\n return false;\n }\n}\n\n/** Serializes a trace line as compact JSON without a trailing newline. */\nexport function serializeEvent(event: TraceEvent): string {\n try {\n return JSON.stringify(event);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Creates (or truncates) an empty JSONL file for a run. Uses {@link ensureTraceDir} then {@link getTraceFilePath}.\n * On failure, retries once under {@link FALLBACK_TRACE_DIR}.\n */\nexport async function initializeTraceFile(\n runId: string,\n traceDir: string,\n): Promise<string | undefined> {\n try {\n const usable = await ensureTraceDir(traceDir);\n const filePath = getTraceFilePath(runId, usable);\n await writeFile(filePath, \"\", \"utf-8\");\n return filePath;\n } catch (e) {\n warn(\"Failed to initialize trace file\", e);\n }\n\n try {\n const usable = await ensureTraceDir(FALLBACK_TRACE_DIR);\n const filePath = getTraceFilePath(runId, usable);\n await writeFile(filePath, \"\", \"utf-8\");\n return filePath;\n } catch (e) {\n warn(\"Failed to initialize trace file on fallback directory\", e);\n return undefined;\n }\n}\n\n/**\n * Appends one validated JSONL line for `event.runId`. Falls back to {@link FALLBACK_TRACE_DIR} on append failure.\n */\nfunction ensureEventWithinBounds(event: TraceEvent): TraceEvent {\n const line = serializeEvent(event);\n if (line === \"\") return event;\n const bytes = Buffer.byteLength(line, \"utf8\");\n if (bytes <= DEFAULT_MAX_EVENT_BYTES) return event;\n return prepareTraceEventForDisk(event, resolveTraceSafetyOptions());\n}\n\nexport async function writeTraceEvent(\n event: TraceEvent,\n traceDir: string,\n): Promise<void> {\n const bounded = ensureEventWithinBounds(event);\n\n if (!validateEvent(bounded)) {\n warn(\"Skipped invalid trace event (validation failed)\");\n return;\n }\n\n const line = serializeEvent(bounded);\n if (line === \"\") {\n warn(\"Skipped trace event (serialization failed)\");\n return;\n }\n\n const payload = `${line}\\n`;\n\n const tryAppend = async (dir: string): Promise<boolean> => {\n try {\n const usable = await ensureTraceDir(dir);\n const filePath = getTraceFilePath(event.runId, usable);\n await appendFile(filePath, payload, \"utf-8\");\n return true;\n } catch {\n return false;\n }\n };\n\n if (await tryAppend(traceDir)) {\n return;\n }\n\n warn(`Failed to append trace event for run ${event.runId}`);\n\n if (await tryAppend(FALLBACK_TRACE_DIR)) {\n return;\n }\n\n warn(\"Failed to append trace event to fallback directory\");\n}\n\n/**\n * Reads raw JSONL file contents for a run, or `undefined` if missing or unreadable.\n */\nexport async function readTraceFile(\n runId: string,\n traceDir: string,\n): Promise<string | undefined> {\n try {\n const filePath = getTraceFilePath(runId, traceDir);\n return await readFile(filePath, \"utf-8\");\n } catch (e) {\n if (e && typeof e === \"object\" && \"code\" in e && e.code === \"ENOENT\") {\n return undefined;\n }\n warn(\"Unexpected error reading trace file\", e);\n return undefined;\n }\n}\n\n/**\n * Parses JSONL into validated {@link TraceEvent} rows (v0.1 native or v0.2 normalized).\n * Invalid lines are skipped with a warning.\n */\nexport async function readTraceEvents(\n runId: string,\n traceDir: string,\n): Promise<TraceEvent[]> {\n try {\n const filePath = getTraceFilePath(runId, traceDir);\n return await readTraceEventsFromFile(filePath);\n } catch (e) {\n warn(\"Failed to read trace events\", e);\n return [];\n }\n}\n\n/**\n * Reads and normalizes trace events from an exact file path.\n * Used by directory scans where the embedded run id may differ from the basename.\n */\nexport async function readTraceEventsFromFile(\n filePath: string,\n): Promise<TraceEvent[]> {\n try {\n const raw = await readFile(filePath, \"utf-8\");\n return parseTraceJsonl(raw, { validate: validateEvent }).events;\n } catch (e) {\n if (e && typeof e === \"object\" && \"code\" in e && e.code === \"ENOENT\") {\n return [];\n }\n warn(\"Failed to read trace events from file\", e);\n return [];\n }\n}\n\n/**\n * Lists `.jsonl` file names in `traceDir`, newest by mtime first (name sort as tie-breaker).\n */\nexport async function listTraceFiles(traceDir: string): Promise<string[]> {\n try {\n const usable = path.resolve(traceDir);\n const names = await readdir(usable);\n const jsonl = names.filter((n) => n.endsWith(\".jsonl\"));\n const withStat = await Promise.all(\n jsonl.map(async (name) => {\n try {\n const st = await stat(path.join(usable, name));\n return { name, mtime: st.mtimeMs };\n } catch {\n return { name, mtime: 0 };\n }\n }),\n );\n withStat.sort((a, b) => {\n if (b.mtime !== a.mtime) return b.mtime - a.mtime;\n return a.name.localeCompare(b.name);\n });\n return withStat.map((x) => x.name);\n } catch {\n return [];\n }\n}\n\n/** Maps a `.jsonl` file name to its run id (basename only; no traversal). */\nexport function getRunIdFromTraceFileName(fileName: string): string | undefined {\n try {\n const base = path.basename(fileName);\n if (!base.endsWith(\".jsonl\")) return undefined;\n const id = base.slice(0, -\".jsonl\".length);\n return id === \"\" ? undefined : id;\n } catch {\n return undefined;\n }\n}\n","import { Redactor } from \"./logs/redactor.js\";\nimport {\n applyProfileMetadataCaps,\n resolveRedactionProfile,\n type ResolvedRedactionProfile,\n} from \"./redaction-profiles.js\";\nimport { serializeEvent } from \"./storage.js\";\nimport type { RedactionRule } from \"./types/log-config.js\";\nimport {\n isPersistedInspectEvent,\n type PersistedInspectError,\n type PersistedInspectEvent,\n type PersistedTokenUsage,\n type PersistedTraceContext,\n} from \"./types/persisted-inspect-event.js\";\nimport type {\n InspectRunOptions,\n RedactionProfile,\n StepMetadata,\n TraceEvent,\n} from \"./types.js\";\n\n/** Default max length for string metadata values (non-preview keys). */\nexport const DEFAULT_MAX_METADATA_VALUE_LENGTH = 2000;\n\n/** Default max length for preview-like metadata keys (contains `preview`, case-insensitive). */\nexport const DEFAULT_MAX_PREVIEW_LENGTH = 500;\n\n/** Default max serialized JSONL line size in bytes (UTF-8). */\nexport const DEFAULT_MAX_EVENT_BYTES = 65_536;\n\n/** Resolved trace safety settings used at write time. */\nexport interface TraceSafetyOptions {\n redactEnabled: boolean;\n redactionRules?: RedactionRule[];\n redactionProfile: RedactionProfile;\n profileExtraKeys: readonly string[];\n maxMetadataValueLength: number;\n maxPreviewLength: number;\n maxEventBytes: number;\n}\n\nexport type { ResolvedRedactionProfile };\nexport { resolveRedactionProfile };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nconst KNOWN_PERSISTED_EVENT_FIELDS = new Set([\n \"schemaVersion\",\n \"eventId\",\n \"runId\",\n \"kind\",\n \"name\",\n \"parentId\",\n \"status\",\n \"timestamp\",\n \"startedAt\",\n \"endedAt\",\n \"durationMs\",\n \"confidence\",\n \"source\",\n \"attributes\",\n \"inputSummary\",\n \"outputSummary\",\n \"error\",\n \"tokenUsage\",\n \"trace\",\n]);\n\nfunction isSafeExtensionFieldName(key: string): boolean {\n return key !== \"__proto__\" && key !== \"constructor\" && key !== \"prototype\";\n}\n\nfunction isPreviewKey(key: string): boolean {\n return key.toLowerCase().includes(\"preview\");\n}\n\nfunction truncateString(value: string, maxLen: number): string {\n if (maxLen <= 0) return \"…\";\n if (value.length <= maxLen) return value;\n return `${value.slice(0, maxLen)}…`;\n}\n\nfunction byteLength(text: string): number {\n return Buffer.byteLength(text, \"utf8\");\n}\n\n/** Resolves {@link InspectRunOptions} trace safety fields with safe defaults. */\nexport function resolveTraceSafetyOptions(\n options?: Pick<\n InspectRunOptions,\n | \"redact\"\n | \"redactionProfile\"\n | \"maxEventBytes\"\n | \"maxMetadataValueLength\"\n | \"maxPreviewLength\"\n >,\n): TraceSafetyOptions {\n const redact = options?.redact;\n let redactEnabled = true;\n let redactionRules: RedactionRule[] | undefined;\n\n if (redact === false) {\n redactEnabled = false;\n } else if (redact === true || redact === undefined) {\n redactEnabled = true;\n } else if (isRecord(redact)) {\n redactEnabled = true;\n redactionRules = redact.rules;\n }\n\n const profile = options?.redactionProfile ?? \"local\";\n const resolvedProfile = resolveRedactionProfile(profile);\n\n const userMaxMetadata =\n typeof options?.maxMetadataValueLength === \"number\" &&\n Number.isFinite(options.maxMetadataValueLength) &&\n options.maxMetadataValueLength >= 0\n ? Math.floor(options.maxMetadataValueLength)\n : undefined;\n const userMaxPreview =\n typeof options?.maxPreviewLength === \"number\" &&\n Number.isFinite(options.maxPreviewLength) &&\n options.maxPreviewLength >= 0\n ? Math.floor(options.maxPreviewLength)\n : undefined;\n\n let maxMetadataValueLength = userMaxMetadata ?? DEFAULT_MAX_METADATA_VALUE_LENGTH;\n let maxPreviewLength = userMaxPreview ?? DEFAULT_MAX_PREVIEW_LENGTH;\n\n if (redactEnabled && profile !== \"local\") {\n const capped = applyProfileMetadataCaps(\n maxMetadataValueLength,\n maxPreviewLength,\n resolvedProfile,\n );\n maxMetadataValueLength = capped.maxMetadataValueLength;\n maxPreviewLength = capped.maxPreviewLength;\n }\n\n return {\n redactEnabled,\n redactionRules,\n redactionProfile: profile,\n profileExtraKeys: redactEnabled ? resolvedProfile.extraKeys : [],\n maxMetadataValueLength,\n maxPreviewLength,\n maxEventBytes:\n typeof options?.maxEventBytes === \"number\" &&\n Number.isFinite(options.maxEventBytes) &&\n options.maxEventBytes > 0\n ? Math.floor(options.maxEventBytes)\n : DEFAULT_MAX_EVENT_BYTES,\n };\n}\n\nfunction boundMetadataValue(\n key: string,\n value: unknown,\n opts: TraceSafetyOptions,\n seen: WeakSet<object>,\n depth: number,\n): unknown {\n if (depth > 32) return \"[MaxDepth]\";\n\n if (typeof value === \"bigint\") {\n return `${value.toString()}n`;\n }\n if (typeof value === \"function\") {\n return \"[Function]\";\n }\n if (typeof value === \"symbol\") {\n return \"[Symbol]\";\n }\n if (typeof value === \"number\" && !Number.isFinite(value)) {\n return String(value);\n }\n if (value === undefined) {\n return null;\n }\n\n if (value === null || typeof value !== \"object\") {\n if (typeof value === \"string\") {\n const max = isPreviewKey(key) ? opts.maxPreviewLength : opts.maxMetadataValueLength;\n return truncateString(value, max);\n }\n return value;\n }\n\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n\n if (Array.isArray(value)) {\n const maxItems = 50;\n const out = value\n .slice(0, maxItems)\n .map((item, index) =>\n boundMetadataValue(String(index), item, opts, seen, depth + 1),\n );\n if (value.length > maxItems) {\n out.push(`…(+${value.length - maxItems} more)`);\n }\n return out;\n }\n\n const record = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n try {\n for (const [k, v] of Object.entries(record)) {\n out[k] = boundMetadataValue(k, v, opts, seen, depth + 1);\n }\n } catch {\n return { truncated: true, reason: \"metadataEnumerationFailed\" };\n }\n return out;\n}\n\nfunction redactMetadata(\n metadata: Record<string, unknown>,\n opts: TraceSafetyOptions,\n): Record<string, unknown> {\n if (!opts.redactEnabled) return { ...metadata };\n const redactor = new Redactor({\n rules: opts.redactionRules,\n extraKeys: opts.profileExtraKeys,\n });\n return redactor.redactRecord(metadata);\n}\n\n/** Redacts (when enabled) and truncates metadata values for disk persistence. */\nexport function prepareMetadataForDisk(\n metadata: Record<string, unknown> | StepMetadata,\n opts: TraceSafetyOptions,\n): Record<string, unknown> {\n try {\n const preBounded = boundMetadataValue(\n \"metadata\",\n metadata,\n opts,\n new WeakSet<object>(),\n 0,\n );\n const redacted = redactMetadata(\n isRecord(preBounded) ? preBounded : {},\n opts,\n );\n const bounded = boundMetadataValue(\n \"metadata\",\n redacted,\n opts,\n new WeakSet<object>(),\n 0,\n );\n return isRecord(bounded) ? bounded : {};\n } catch {\n return { truncated: true, reason: \"metadataPreparationFailed\" };\n }\n}\n\nfunction truncateErrorStack(\n event: TraceEvent,\n maxLen: number,\n): TraceEvent {\n if (event.event !== \"run_completed\" && event.event !== \"step_completed\") {\n return event;\n }\n if (!event.error?.stack || typeof event.error.stack !== \"string\") {\n return event;\n }\n return {\n ...event,\n error: {\n ...event.error,\n stack: truncateString(event.error.stack, maxLen),\n },\n };\n}\n\nfunction replaceMetadataWithTruncationMarker(\n event: TraceEvent,\n originalApproxBytes: number,\n): TraceEvent {\n const marker = {\n truncated: true,\n reason: \"maxEventBytes\",\n originalApproxBytes,\n };\n if (event.event === \"run_started\") {\n return { ...event, metadata: marker };\n }\n if (event.event === \"step_started\") {\n return { ...event, metadata: marker };\n }\n return event;\n}\n\nfunction shrinkMetadataLimits(\n opts: TraceSafetyOptions,\n factor: number,\n): TraceSafetyOptions {\n return {\n ...opts,\n maxMetadataValueLength: Math.max(32, Math.floor(opts.maxMetadataValueLength * factor)),\n maxPreviewLength: Math.max(16, Math.floor(opts.maxPreviewLength * factor)),\n };\n}\n\nfunction applyMetadataToEvent(\n event: TraceEvent,\n metadata: Record<string, unknown>,\n): TraceEvent {\n if (event.event === \"run_started\") {\n return { ...event, metadata };\n }\n if (event.event === \"step_started\") {\n return { ...event, metadata: metadata as StepMetadata };\n }\n return event;\n}\n\nfunction eventHasMetadata(event: TraceEvent): boolean {\n return (\n (event.event === \"run_started\" || event.event === \"step_started\") &&\n event.metadata !== undefined\n );\n}\n\nfunction getEventMetadata(event: TraceEvent): Record<string, unknown> | undefined {\n if (event.event === \"run_started\" || event.event === \"step_started\") {\n return event.metadata as Record<string, unknown> | undefined;\n }\n return undefined;\n}\n\n/**\n * Applies redaction, metadata truncation, and final serialized size bounds.\n * Never throws; returns a schema-valid event or a minimally truncated variant.\n */\nexport function prepareTraceEventForDisk(\n event: TraceEvent,\n opts: TraceSafetyOptions,\n): TraceEvent {\n try {\n let working: TraceEvent = { ...event };\n\n const rawMetadata = getEventMetadata(working);\n if (rawMetadata !== undefined) {\n const safe = prepareMetadataForDisk(rawMetadata, opts);\n working = applyMetadataToEvent(working, safe);\n }\n\n let serialized = serializeEvent(working);\n if (serialized === \"\") {\n return working;\n }\n\n let bytes = byteLength(serialized);\n if (bytes <= opts.maxEventBytes) {\n return working;\n }\n\n if (rawMetadata !== undefined) {\n for (const factor of [0.5, 0.25, 0.1]) {\n const tighter = shrinkMetadataLimits(opts, factor);\n const shrunk = prepareMetadataForDisk(rawMetadata, tighter);\n working = applyMetadataToEvent(working, shrunk);\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n }\n\n working = replaceMetadataWithTruncationMarker(working, bytes);\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n }\n\n working = truncateErrorStack(working, Math.min(opts.maxMetadataValueLength, 500));\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n\n if (eventHasMetadata(working)) {\n working = replaceMetadataWithTruncationMarker(working, bytes);\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n\n if (working.event === \"run_started\") {\n const { metadata: _meta, ...rest } = working;\n working = rest;\n } else if (working.event === \"step_started\") {\n const { metadata: _meta, ...rest } = working;\n working = rest;\n }\n }\n\n return working;\n } catch {\n if (event.event === \"run_started\" || event.event === \"step_started\") {\n return applyMetadataToEvent(event, {\n truncated: true,\n reason: \"prepareTraceEventFailed\",\n });\n }\n return event;\n }\n}\n\nfunction safeGet(record: Record<string, unknown>, key: string): unknown {\n try {\n return record[key];\n } catch {\n return undefined;\n }\n}\n\nfunction optionalBoundedString(\n value: unknown,\n _key: string,\n opts: TraceSafetyOptions,\n): string | undefined {\n if (typeof value !== \"string\") return undefined;\n return truncateString(value, opts.maxMetadataValueLength);\n}\n\nfunction requiredBoundedString(\n value: unknown,\n key: string,\n opts: TraceSafetyOptions,\n): string | undefined {\n const out = optionalBoundedString(value, key, opts);\n return out && out.length > 0 ? out : undefined;\n}\n\nfunction preparePersistedSummaryForDisk(\n key: \"input\" | \"output\",\n value: unknown,\n opts: TraceSafetyOptions,\n): unknown {\n try {\n const redactor = new Redactor({\n rules: opts.redactionRules,\n extraKeys: opts.profileExtraKeys,\n });\n const redacted = opts.redactEnabled ? redactor.redactValue(key, value) : value;\n return boundMetadataValue(key, redacted, opts, new WeakSet<object>(), 0);\n } catch {\n return { truncated: true, reason: \"summaryPreparationFailed\" };\n }\n}\n\nfunction preparePersistedErrorForDisk(\n value: unknown,\n opts: TraceSafetyOptions,\n): PersistedInspectError | undefined {\n if (!isRecord(value)) return undefined;\n\n try {\n const redactor = new Redactor({\n rules: opts.redactionRules,\n extraKeys: opts.profileExtraKeys,\n });\n const rawMessage = safeGet(value, \"message\");\n const redactedMessage = opts.redactEnabled\n ? redactor.redactValue(\"message\", rawMessage)\n : rawMessage;\n const boundedMessage = boundMetadataValue(\n \"message\",\n redactedMessage,\n opts,\n new WeakSet<object>(),\n 0,\n );\n const message =\n typeof boundedMessage === \"string\" && boundedMessage.length > 0\n ? boundedMessage\n : \"Unknown error\";\n\n const out: PersistedInspectError = { message };\n const name = optionalBoundedString(safeGet(value, \"name\"), \"name\", opts);\n const code = optionalBoundedString(safeGet(value, \"code\"), \"code\", opts);\n if (name !== undefined) out.name = name;\n if (code !== undefined) out.code = code;\n return out;\n } catch {\n return { message: \"Error preparation failed\" };\n }\n}\n\nfunction prepareTokenUsage(value: unknown): PersistedTokenUsage | undefined {\n if (!isRecord(value)) return undefined;\n const out: PersistedTokenUsage = {};\n for (const key of [\"input\", \"output\", \"total\", \"cached\"] as const) {\n const item = safeGet(value, key);\n if (typeof item === \"number\" && Number.isFinite(item) && item >= 0) {\n out[key] = item;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction prepareTraceContext(\n value: unknown,\n opts: TraceSafetyOptions,\n): PersistedTraceContext | undefined {\n if (!isRecord(value)) return undefined;\n const out: PersistedTraceContext = {};\n const traceId = optionalBoundedString(safeGet(value, \"traceId\"), \"traceId\", opts);\n const spanId = optionalBoundedString(safeGet(value, \"spanId\"), \"spanId\", opts);\n const parentSpanId = optionalBoundedString(\n safeGet(value, \"parentSpanId\"),\n \"parentSpanId\",\n opts,\n );\n if (traceId !== undefined) out.traceId = traceId;\n if (spanId !== undefined) out.spanId = spanId;\n if (parentSpanId !== undefined) out.parentSpanId = parentSpanId;\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction preparePersistedExtensionFieldForDisk(\n key: string,\n value: unknown,\n opts: TraceSafetyOptions,\n): unknown {\n if (isRecord(value)) {\n return prepareMetadataForDisk(value, opts);\n }\n\n const prepared = prepareMetadataForDisk({ [key]: value }, opts);\n return Object.prototype.hasOwnProperty.call(prepared, key)\n ? prepared[key]\n : undefined;\n}\n\nfunction preserveV10ExtensionFields(\n source: Record<string, unknown>,\n candidate: PersistedInspectEvent,\n opts: TraceSafetyOptions,\n): void {\n if (candidate.schemaVersion !== \"1.0\") return;\n\n for (const [key, value] of Object.entries(source)) {\n if (\n KNOWN_PERSISTED_EVENT_FIELDS.has(key) ||\n !isSafeExtensionFieldName(key)\n ) {\n continue;\n }\n\n const prepared = preparePersistedExtensionFieldForDisk(key, value, opts);\n if (prepared !== undefined) {\n candidate[key] = prepared;\n }\n }\n}\n\nfunction serializedPersistedEvent(event: PersistedInspectEvent): string | undefined {\n try {\n return JSON.stringify(event);\n } catch {\n return undefined;\n }\n}\n\nfunction persistedEventByteLength(event: PersistedInspectEvent): number | undefined {\n const serialized = serializedPersistedEvent(event);\n return serialized === undefined ? undefined : byteLength(serialized);\n}\n\nfunction minimalPersistedEvent(\n event: PersistedInspectEvent,\n opts: TraceSafetyOptions,\n originalApproxBytes: number,\n): PersistedInspectEvent {\n return {\n schemaVersion: event.schemaVersion,\n eventId: truncateString(event.eventId, 128),\n runId: truncateString(event.runId, 128),\n kind: event.kind,\n name: truncateString(event.name, 128),\n ...(event.status !== undefined ? { status: event.status } : {}),\n timestamp: truncateString(event.timestamp, 128),\n confidence: event.confidence,\n source: {\n type: event.source.type,\n ...(event.source.name !== undefined\n ? { name: truncateString(event.source.name, 128) }\n : {}),\n ...(event.source.version !== undefined\n ? { version: truncateString(event.source.version, 128) }\n : {}),\n },\n attributes: {\n truncated: true,\n reason: \"maxEventBytes\",\n originalApproxBytes,\n maxEventBytes: opts.maxEventBytes,\n },\n };\n}\n\nfunction tinyPersistedEvent(event: PersistedInspectEvent): PersistedInspectEvent {\n return {\n schemaVersion: event.schemaVersion,\n eventId: truncateString(event.eventId, 32),\n runId: truncateString(event.runId, 32),\n kind: event.kind,\n name: truncateString(event.name, 32),\n timestamp: truncateString(event.timestamp, 32),\n confidence: event.confidence,\n source: { type: event.source.type },\n attributes: { truncated: true, reason: \"maxEventBytes\" },\n };\n}\n\nfunction enforcePersistedEventSize(\n event: PersistedInspectEvent,\n opts: TraceSafetyOptions,\n): PersistedInspectEvent | undefined {\n const bytes = persistedEventByteLength(event);\n if (bytes === undefined) return undefined;\n if (bytes <= opts.maxEventBytes) return event;\n\n const minimal = minimalPersistedEvent(event, opts, bytes);\n const minimalBytes = persistedEventByteLength(minimal);\n if (minimalBytes !== undefined && minimalBytes <= opts.maxEventBytes) {\n return minimal;\n }\n\n const tiny = tinyPersistedEvent(event);\n return isPersistedInspectEvent(tiny) ? tiny : undefined;\n}\n\n/**\n * Prepares persisted inspect events for built-in persistence.\n *\n * The helper is intentionally non-throwing: invalid required fields return\n * `undefined`; supported optional fields are redacted, bounded, JSON-safe, and\n * final serialized-size checked before a writer sees the event.\n */\nexport function preparePersistedInspectEventForWrite(\n value: unknown,\n opts: TraceSafetyOptions = resolveTraceSafetyOptions(),\n): PersistedInspectEvent | undefined {\n try {\n if (!isRecord(value)) return undefined;\n\n const source = safeGet(value, \"source\");\n if (!isRecord(source)) return undefined;\n\n const candidate: PersistedInspectEvent = {\n schemaVersion: safeGet(value, \"schemaVersion\") as PersistedInspectEvent[\"schemaVersion\"],\n eventId: requiredBoundedString(safeGet(value, \"eventId\"), \"eventId\", opts) ?? \"\",\n runId: requiredBoundedString(safeGet(value, \"runId\"), \"runId\", opts) ?? \"\",\n kind: safeGet(value, \"kind\") as PersistedInspectEvent[\"kind\"],\n name: requiredBoundedString(safeGet(value, \"name\"), \"name\", opts) ?? \"\",\n timestamp: requiredBoundedString(safeGet(value, \"timestamp\"), \"timestamp\", opts) ?? \"\",\n confidence: safeGet(value, \"confidence\") as PersistedInspectEvent[\"confidence\"],\n source: {\n type: safeGet(source, \"type\") as PersistedInspectEvent[\"source\"][\"type\"],\n },\n };\n\n const parentId = requiredBoundedString(safeGet(value, \"parentId\"), \"parentId\", opts);\n const status = safeGet(value, \"status\");\n const startedAt = optionalBoundedString(safeGet(value, \"startedAt\"), \"startedAt\", opts);\n const endedAt = optionalBoundedString(safeGet(value, \"endedAt\"), \"endedAt\", opts);\n const durationMs = safeGet(value, \"durationMs\");\n const sourceName = optionalBoundedString(safeGet(source, \"name\"), \"name\", opts);\n const sourceVersion = optionalBoundedString(safeGet(source, \"version\"), \"version\", opts);\n\n if (parentId !== undefined) candidate.parentId = parentId;\n if (\n status === \"running\" ||\n status === \"ok\" ||\n status === \"error\" ||\n status === \"unknown\"\n ) {\n candidate.status = status;\n }\n if (startedAt !== undefined) candidate.startedAt = startedAt;\n if (endedAt !== undefined) candidate.endedAt = endedAt;\n if (\n typeof durationMs === \"number\" &&\n Number.isFinite(durationMs) &&\n durationMs >= 0\n ) {\n candidate.durationMs = durationMs;\n }\n if (sourceName !== undefined) candidate.source.name = sourceName;\n if (sourceVersion !== undefined) candidate.source.version = sourceVersion;\n\n const attributes = safeGet(value, \"attributes\");\n if (isRecord(attributes)) {\n candidate.attributes = prepareMetadataForDisk(attributes, opts);\n }\n\n if (safeGet(value, \"inputSummary\") !== undefined) {\n candidate.inputSummary = preparePersistedSummaryForDisk(\n \"input\",\n safeGet(value, \"inputSummary\"),\n opts,\n );\n }\n if (safeGet(value, \"outputSummary\") !== undefined) {\n candidate.outputSummary = preparePersistedSummaryForDisk(\n \"output\",\n safeGet(value, \"outputSummary\"),\n opts,\n );\n }\n\n const error = preparePersistedErrorForDisk(safeGet(value, \"error\"), opts);\n if (error !== undefined) candidate.error = error;\n\n const tokenUsage = prepareTokenUsage(safeGet(value, \"tokenUsage\"));\n if (tokenUsage !== undefined) candidate.tokenUsage = tokenUsage;\n\n const trace = prepareTraceContext(safeGet(value, \"trace\"), opts);\n if (trace !== undefined) candidate.trace = trace;\n\n preserveV10ExtensionFields(value, candidate, opts);\n\n if (!isPersistedInspectEvent(candidate)) return undefined;\n return enforcePersistedEventSize(candidate, opts);\n } catch {\n return undefined;\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport { extractCorrelationMetadata } from \"./correlation-metadata.js\";\nimport type { ExecutionContext, TraceCorrelationMetadata } from \"./types.js\";\nimport {\n resolveTraceSafetyOptions,\n type TraceSafetyOptions,\n} from \"./trace-event-safety.js\";\n\ntype RuntimeExecutionContext = ExecutionContext & {\n currentStepId?: string;\n currentDepth: number;\n traceSafety: TraceSafetyOptions;\n};\n\nconst storage = new AsyncLocalStorage<RuntimeExecutionContext>();\n\nfunction toPublicContext(ctx: RuntimeExecutionContext): ExecutionContext {\n return {\n runId: ctx.runId,\n runName: ctx.runName,\n traceDir: ctx.traceDir,\n silent: ctx.silent,\n metadata: ctx.metadata,\n };\n}\n\nfunction invoke<T>(fn: () => T | Promise<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n try {\n Promise.resolve(fn()).then(resolve, reject);\n } catch (e) {\n reject(e);\n }\n });\n}\n\n/** Returns the active run context, without internal step fields. */\nexport function getCurrentContext(): ExecutionContext | undefined {\n try {\n const s = storage.getStore();\n if (!s) return undefined;\n return toPublicContext(s);\n } catch {\n return undefined;\n }\n}\n\n/** Active `runId` when inside `runWithContext`, else `undefined`. */\nexport function getCurrentRunId(): string | undefined {\n try {\n return storage.getStore()?.runId;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Correlation metadata for the active run (`correlationId`, `requestId`, `decisionId`, `groupId`).\n * `undefined` outside `inspectRun` / `maybeInspectRun` or when no correlation fields were set.\n */\nexport function getCurrentCorrelationMetadata():\n | TraceCorrelationMetadata\n | undefined {\n try {\n return extractCorrelationMetadata(storage.getStore()?.metadata);\n } catch {\n return undefined;\n }\n}\n\n/** Active `runName` when inside `runWithContext`, else `undefined`. */\nexport function getCurrentRunName(): string | undefined {\n try {\n return storage.getStore()?.runName;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Active step id in this async scope (parent for nested `step()` calls).\n * `undefined` at run root or outside any run.\n */\nexport function getCurrentStepId(): string | undefined {\n try {\n return storage.getStore()?.currentStepId;\n } catch {\n return undefined;\n }\n}\n\n/** Alias of {@link getCurrentStepId} for readability in step instrumentation. */\nexport function getParentStepId(): string | undefined {\n return getCurrentStepId();\n}\n\n/**\n * Nesting depth: `0` at run root, increments by one per nested `runWithStepContext`.\n * Returns `0` outside any run.\n */\nexport function getCurrentDepth(): number {\n try {\n const d = storage.getStore()?.currentDepth;\n return typeof d === \"number\" && Number.isFinite(d) ? d : 0;\n } catch {\n return 0;\n }\n}\n\nexport function hasActiveContext(): boolean {\n try {\n return storage.getStore() !== undefined;\n } catch {\n return false;\n }\n}\n\nexport function getTraceDirFromContext(): string | undefined {\n try {\n return storage.getStore()?.traceDir;\n } catch {\n return undefined;\n }\n}\n\nexport function isSilentContext(): boolean {\n try {\n const s = storage.getStore();\n return s ? s.silent : false;\n } catch {\n return false;\n }\n}\n\n/** Resolved trace safety settings for the active run (redaction + size bounds). */\nexport function getTraceSafetyFromContext(): TraceSafetyOptions | undefined {\n try {\n return storage.getStore()?.traceSafety;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Runs `fn` with a fresh AgentInspect run context (depth 0, no active step).\n * Propagates sync/async results and rejections; does not swallow user errors.\n */\nexport function runWithContext<T>(\n context: ExecutionContext,\n fn: () => Promise<T> | T,\n traceSafety: TraceSafetyOptions = resolveTraceSafetyOptions(),\n): Promise<T> {\n const runtime: RuntimeExecutionContext = {\n runId: context.runId,\n runName: context.runName,\n traceDir: context.traceDir,\n silent: context.silent,\n metadata: context.metadata,\n traceSafety,\n currentDepth: 0,\n };\n\n return new Promise((resolve, reject) => {\n storage.run(runtime, () => {\n try {\n Promise.resolve(fn()).then(resolve, reject);\n } catch (e) {\n reject(e);\n }\n });\n });\n}\n\n/**\n * Runs `fn` with `stepId` as the active step (incremented depth).\n * If no run is active, runs `fn` without altering async context.\n */\nexport function runWithStepContext<T>(\n stepId: string,\n fn: () => Promise<T> | T,\n): Promise<T> {\n let parent: RuntimeExecutionContext | undefined;\n try {\n parent = storage.getStore();\n } catch {\n parent = undefined;\n }\n\n if (!parent) {\n return invoke(fn);\n }\n\n const derived: RuntimeExecutionContext = {\n runId: parent.runId,\n runName: parent.runName,\n traceDir: parent.traceDir,\n silent: parent.silent,\n metadata: parent.metadata,\n traceSafety: parent.traceSafety,\n currentStepId: stepId,\n currentDepth: parent.currentDepth + 1,\n };\n\n return new Promise((resolve, reject) => {\n storage.run(derived, () => {\n try {\n Promise.resolve(fn()).then(resolve, reject);\n } catch (e) {\n reject(e);\n }\n });\n });\n}\n","import chalk from \"chalk\";\n\nimport { isSilentContext } from \"./context.js\";\nimport type { ErrorInfo, RunStatus, StepStatus } from \"./types.js\";\nimport { formatDuration, truncateName } from \"./utils.js\";\n\n/** Two spaces per nesting level in terminal output. */\nexport const TERMINAL_INDENT = \" \";\n\n/** Max display length for names in terminal output. */\nexport const MAX_TERMINAL_NAME_LENGTH = 80;\n\n/** Max nesting depth used for indentation (prevents huge indents). */\nexport const MAX_TERMINAL_DEPTH = 10;\n\nfunction normalizeDepth(depth: number): number {\n if (!Number.isFinite(depth) || depth < 0) {\n return 0;\n }\n return Math.min(Math.floor(depth), MAX_TERMINAL_DEPTH);\n}\n\nfunction safePrint(line = \"\"): void {\n try {\n console.log(line);\n } catch {\n /* never break callers */\n }\n}\n\n/** Indentation string for a nesting depth (capped, never negative). */\nexport function getIndent(depth: number): string {\n return TERMINAL_INDENT.repeat(normalizeDepth(depth));\n}\n\n/** Truncates a display name for terminal use; invalid input becomes `\"unnamed\"`. */\nexport function formatTerminalName(name: string): string {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n return \"unnamed\";\n }\n return truncateName(name, MAX_TERMINAL_NAME_LENGTH);\n}\n\nfunction getStatusIcon(status: StepStatus | RunStatus): string {\n if (status === \"success\") return chalk.green(\"✔\");\n if (status === \"error\") return chalk.red(\"✖\");\n return chalk.yellow(\"⏳\");\n}\n\n/** Renders a single step line (colored); does not consult silent mode. */\nexport function renderStepLine(\n name: string,\n durationMs: number | undefined,\n status: StepStatus,\n depth?: number,\n): string {\n try {\n const nm = formatTerminalName(name);\n const ind = getIndent(depth ?? 0);\n if (status === \"running\" && durationMs === undefined) {\n return `${ind}${chalk.yellow(\"⏳\")} ${nm}`;\n }\n const hasDur =\n durationMs !== undefined && Number.isFinite(durationMs as number);\n const dur = hasDur ? formatDuration(durationMs as number) : undefined;\n if (status === \"running\") {\n return dur !== undefined\n ? `${ind}${chalk.yellow(\"⏳\")} ${nm} (${dur})`\n : `${ind}${chalk.yellow(\"⏳\")} ${nm}`;\n }\n if (!hasDur || dur === undefined) {\n return `${ind}${chalk.yellow(\"⏳\")} ${nm}`;\n }\n if (status === \"success\") {\n return `${ind}${getStatusIcon(\"success\")} ${nm} (${dur})`;\n }\n return `${ind}${getStatusIcon(\"error\")} ${nm} (${dur})`;\n } catch {\n return \"\";\n }\n}\n\n/** Renders an error summary line (no stack in MVP). */\nexport function renderErrorLine(error: ErrorInfo, depth?: number): string {\n try {\n const msg =\n typeof error.message === \"string\" ? error.message : \"\";\n const ind = getIndent((depth ?? 0) + 1);\n return `${ind}Error: ${msg}`;\n } catch {\n return \"\";\n }\n}\n\n/** Plain-text run summary lines (no chalk) for stable testing and CLI reuse. */\nexport function renderRunSummary(\n durationMs: number,\n status: RunStatus,\n traceFilePath?: string,\n): string[] {\n try {\n const dur = Number.isFinite(durationMs)\n ? formatDuration(durationMs)\n : formatDuration(0);\n const head =\n status === \"error\" ? `Failed in ${dur}` : `Completed in ${dur}`;\n const lines = [head];\n if (traceFilePath !== undefined && traceFilePath.trim() !== \"\") {\n lines.push(`Trace: ${traceFilePath}`);\n }\n return lines;\n } catch {\n return [];\n }\n}\n\n/** Prints run header with icon and dim run id. */\nexport function printRunStart(runId: string, name: string): void {\n if (isSilentContext()) return;\n try {\n safePrint(\"\");\n const header = `${chalk.cyan.bold(\"🔍 AgentInspect:\")} ${formatTerminalName(name)} ${chalk.dim(`(${runId})`)}`;\n safePrint(header);\n } catch {\n /* noop */\n }\n}\n\n/** Prints a running step line. */\nexport function printStepStart(name: string, depth = 0): void {\n if (isSilentContext()) return;\n try {\n safePrint(renderStepLine(name, undefined, \"running\", depth));\n } catch {\n /* noop */\n }\n}\n\n/** Prints a completed step line with duration and status icon. */\nexport function printStepComplete(\n name: string,\n durationMs: number,\n status: StepStatus,\n depth = 0,\n): void {\n if (isSilentContext()) return;\n try {\n safePrint(renderStepLine(name, durationMs, status, depth));\n } catch {\n /* noop */\n }\n}\n\n/** Prints a structured error line (message only, no stack). */\nexport function printError(error: ErrorInfo, depth = 0): void {\n if (isSilentContext()) return;\n try {\n safePrint(renderErrorLine(error, depth));\n } catch {\n /* noop */\n }\n}\n\n/** Prints run completion summary and optional trace path. */\nexport function printRunComplete(\n _name: string,\n _runId: string,\n durationMs: number,\n status: RunStatus,\n traceFilePath?: string,\n): void {\n if (isSilentContext()) return;\n try {\n const lines = renderRunSummary(durationMs, status, traceFilePath);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n if (i === 0) {\n const color =\n status === \"error\"\n ? chalk.red\n : status === \"running\"\n ? chalk.yellow\n : chalk.green;\n safePrint(color(line));\n } else {\n safePrint(chalk.dim(line));\n }\n }\n } catch {\n /* noop */\n }\n}\n\n/** Prints which step failed. */\nexport function printFailedAt(stepName: string): void {\n if (isSilentContext()) return;\n try {\n safePrint(`Failed at: ${formatTerminalName(stepName)}`);\n } catch {\n /* noop */\n }\n}\n","import {\n getCurrentContext,\n getCurrentDepth,\n getParentStepId,\n getTraceSafetyFromContext,\n runWithStepContext,\n} from \"./context.js\";\nimport type { StepOptions, StepType, TraceEvent } from \"./types.js\";\nimport { writeTraceEvent } from \"./storage.js\";\nimport { printFailedAt, printError, printStepComplete, printStepStart } from \"./terminal.js\";\nimport { prepareTraceEventForDisk } from \"./trace-event-safety.js\";\nimport { createStepId, formatError, truncateName, warn } from \"./utils.js\";\n\nfunction normalizeStepName(name: unknown): string {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n return \"unnamed-step\";\n }\n return truncateName(name.trim(), 100);\n}\n\nasync function safeInstrumentation(\n label: string,\n op: () => void | Promise<void>,\n): Promise<void> {\n try {\n await Promise.resolve(op());\n } catch (e) {\n warn(`step: ${label}`, e);\n }\n}\n\nasync function stepImpl<T>(\n name: string,\n fn: () => Promise<T> | T,\n options?: StepOptions,\n): Promise<T> {\n if (typeof fn !== \"function\") {\n throw new TypeError(\"step requires `fn` to be a function\");\n }\n\n const stepName = normalizeStepName(name);\n const context = getCurrentContext();\n\n if (!context) {\n warn(\"step() called outside inspectRun(); executing without instrumentation\");\n return Promise.resolve(fn());\n }\n\n const stepId = createStepId();\n const renderDepth = getCurrentDepth();\n const parentId = getParentStepId();\n const stepType: StepType = options?.type ?? \"logic\";\n const metadata = options?.metadata;\n const traceSafety = getTraceSafetyFromContext();\n const startTime = Date.now();\n\n await safeInstrumentation(\"writeTraceEvent(step_started)\", async () => {\n const started: TraceEvent = {\n schemaVersion: \"0.1\",\n event: \"step_started\",\n timestamp: startTime,\n runId: context.runId,\n stepId,\n ...(typeof parentId === \"string\" && parentId.trim() !== \"\"\n ? { parentId }\n : {}),\n name: stepName,\n type: stepType,\n startTime,\n ...(metadata !== undefined ? { metadata } : {}),\n };\n const safe =\n traceSafety !== undefined\n ? prepareTraceEventForDisk(started, traceSafety)\n : started;\n await writeTraceEvent(safe, context.traceDir);\n });\n\n await safeInstrumentation(\"printStepStart\", () => {\n printStepStart(stepName, renderDepth);\n });\n\n let result: T;\n try {\n result = await runWithStepContext(stepId, async () => {\n return await Promise.resolve(fn());\n });\n } catch (userError) {\n const endTime = Date.now();\n const durationMs = endTime - startTime;\n const formatted = formatError(userError);\n\n await safeInstrumentation(\"writeTraceEvent(step_completed error)\", async () => {\n const completed: TraceEvent = {\n schemaVersion: \"0.1\",\n event: \"step_completed\",\n timestamp: endTime,\n runId: context.runId,\n stepId,\n status: \"error\",\n endTime,\n durationMs,\n error: formatted,\n };\n const safe =\n traceSafety !== undefined\n ? prepareTraceEventForDisk(completed, traceSafety)\n : completed;\n await writeTraceEvent(safe, context.traceDir);\n });\n\n await safeInstrumentation(\"printStepComplete(error)\", () => {\n printStepComplete(stepName, durationMs, \"error\", renderDepth);\n });\n await safeInstrumentation(\"printError\", () => {\n printError(formatted, renderDepth);\n });\n await safeInstrumentation(\"printFailedAt\", () => {\n printFailedAt(stepName);\n });\n\n throw userError;\n }\n\n const endTime = Date.now();\n const durationMs = endTime - startTime;\n\n await safeInstrumentation(\"writeTraceEvent(step_completed success)\", async () => {\n const completed: TraceEvent = {\n schemaVersion: \"0.1\",\n event: \"step_completed\",\n timestamp: endTime,\n runId: context.runId,\n stepId,\n status: \"success\",\n endTime,\n durationMs,\n };\n const safe =\n traceSafety !== undefined\n ? prepareTraceEventForDisk(completed, traceSafety)\n : completed;\n await writeTraceEvent(safe, context.traceDir);\n });\n\n await safeInstrumentation(\"printStepComplete(success)\", () => {\n printStepComplete(stepName, durationMs, \"success\", renderDepth);\n });\n\n return result;\n}\n\n/**\n * Stable v1.0 API for instrumenting a named step inside an AgentInspect run.\n *\n * Callable step tracer plus {@link step.llm} and {@link step.tool} shortcuts.\n */\nexport type StepFunction = {\n <T>(name: string, fn: () => Promise<T> | T, options?: StepOptions): Promise<T>;\n llm: <T>(model: string, fn: () => Promise<T> | T) => Promise<T>;\n tool: <T>(toolName: string, fn: () => Promise<T> | T) => Promise<T>;\n};\n\nasync function stepLlm<T>(model: string, fn: () => Promise<T> | T): Promise<T> {\n const modelName =\n typeof model === \"string\" && model.trim() !== \"\"\n ? model.trim()\n : \"unknown-model\";\n return stepImpl<T>(`llm:${modelName}`, fn, {\n type: \"llm\",\n metadata: { model: modelName },\n });\n}\n\nasync function stepTool<T>(\n toolName: string,\n fn: () => Promise<T> | T,\n): Promise<T> {\n const normalized =\n typeof toolName === \"string\" && toolName.trim() !== \"\"\n ? toolName.trim()\n : \"unknown-tool\";\n return stepImpl<T>(`tool:${normalized}`, fn, {\n type: \"tool\",\n metadata: { toolName: normalized },\n });\n}\n\n/**\n * Traces a named unit of work inside `inspectRun` (`step_started` / `step_completed`, optional terminal).\n * Outside a run, executes `fn` with a warn only. Preserves return values and rethrows user errors unchanged.\n *\n * - `step.llm(model, fn)` — `type: \"llm\"`, `metadata.model` (no SDK calls or token counting).\n * - `step.tool(toolName, fn)` — `type: \"tool\"`, `metadata.toolName` (no framework interception).\n */\nexport const step = Object.assign(stepImpl, {\n llm: stepLlm,\n tool: stepTool,\n}) as StepFunction;\n","import { step } from \"agent-inspect\";\n\nimport { hashServerUrl, summarizeMcpValue } from \"./summarize.js\";\nimport type {\n McpClientLike,\n McpClientTracerOptions,\n McpTraceMetadata,\n} from \"./types.js\";\n\nlet toolCallCounter = 0;\n\nfunction nextToolCallId(prefix?: string): string {\n toolCallCounter += 1;\n const base = prefix?.trim() || \"mcp\";\n return `${base}-${toolCallCounter}`;\n}\n\nfunction baseMetadata(\n options: McpClientTracerOptions,\n overrides: Partial<McpTraceMetadata> = {},\n): Record<string, unknown> {\n const metadata: McpTraceMetadata = {\n source: { type: \"mcp-client\" },\n ...(options.serverName ? { mcpServerName: options.serverName } : {}),\n ...(options.serverUrl\n ? { mcpServerUrlHash: hashServerUrl(options.serverUrl) }\n : {}),\n ...(options.sessionId ? { sessionId: options.sessionId } : {}),\n ...overrides,\n };\n return { ...(options.metadata ?? {}), ...metadata };\n}\n\n/**\n * Wraps an MCP client so tools/list and tools/call emit local tool steps.\n * Telemetry only — does not proxy network behavior beyond the wrapped client.\n */\nexport function wrapMcpClient<T extends McpClientLike>(\n client: T,\n options: McpClientTracerOptions = {},\n): T {\n const maxSummaryLength = options.maxSummaryLength ?? 240;\n const wrapped = { ...client } as T;\n\n if (typeof client.listTools === \"function\") {\n const listTools = client.listTools.bind(client);\n wrapped.listTools = async (params?: unknown) =>\n step(\n \"mcp:tools/list\",\n async () => {\n const result = await listTools(params);\n return result;\n },\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: \"tools/list\",\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n }),\n },\n );\n }\n\n const callTool = client.callTool.bind(client);\n wrapped.callTool = async (params) =>\n step(\n `mcp:${params.name}`,\n async () => callTool(params),\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: params.name,\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n argumentSummary: summarizeMcpValue(\n params.arguments ?? {},\n maxSummaryLength,\n ),\n }),\n },\n );\n\n return wrapped;\n}\n\n/** @internal resets tool call ids for deterministic tests */\nexport function resetMcpToolCallIdsForTests(): void {\n toolCallCounter = 0;\n}\n"]}
1
+ {"version":3,"sources":["../src/summarize.ts","../../core/src/logs/redactor.ts","../../core/src/redaction-profiles.ts","../../core/src/types.ts","../../core/src/utils/duration.ts","../../core/src/utils.ts","../../core/src/storage.ts","../../core/src/trace-event-safety.ts","../../core/src/context.ts","../../core/src/terminal.ts","../../core/src/step.ts","../src/wrap.ts"],"names":["formatDuration","isRecord","out","AsyncLocalStorage","endTime","durationMs"],"mappings":"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","file":"index.mjs","sourcesContent":["const DEFAULT_MAX_SUMMARY_LENGTH = 240;\n\nexport function summarizeMcpValue(\n value: unknown,\n maxLength = DEFAULT_MAX_SUMMARY_LENGTH,\n): string {\n let text: string;\n try {\n if (typeof value === \"string\") {\n text = value;\n } else {\n text = JSON.stringify(value);\n }\n } catch {\n text = String(value);\n }\n if (text.length <= maxLength) return text;\n return `${text.slice(0, Math.max(0, maxLength - 3))}...`;\n}\n\nexport function hashServerUrl(url: string): string {\n let hash = 0;\n for (let i = 0; i < url.length; i += 1) {\n hash = (hash * 31 + url.charCodeAt(i)) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n","import crypto from \"node:crypto\";\n\nimport type { RedactionRule } from \"../types/log-config.js\";\n\nexport const DEFAULT_REDACT_KEYS = [\n \"authorization\",\n \"cookie\",\n \"token\",\n \"apiKey\",\n \"password\",\n \"secret\",\n \"email\",\n] as const;\n\nexport interface RedactorOptions {\n rules?: RedactionRule[];\n /** Additional exact keys (case-insensitive) to redact in addition to defaults. */\n extraKeys?: readonly string[];\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction toKey(s: string): string {\n return s.toLowerCase();\n}\n\nfunction stableHash(value: string): string {\n const h = crypto.createHash(\"sha256\").update(value, \"utf8\").digest(\"hex\");\n return h.slice(0, 8);\n}\n\ntype CompiledRule =\n | { key: string; strategy: \"full\" }\n | { key: string; strategy: \"prefix\"; keep: number }\n | { key: string; strategy: \"hash\" };\n\nfunction compileRules(\n rules?: RedactionRule[],\n extraKeys?: readonly string[],\n): CompiledRule[] {\n const out = new Map<string, CompiledRule>();\n\n const set = (r: CompiledRule) => {\n const k = toKey(r.key);\n out.set(k, { ...r, key: k } as CompiledRule);\n };\n\n for (const k of DEFAULT_REDACT_KEYS) {\n set({ key: k, strategy: \"full\" });\n }\n\n for (const k of extraKeys ?? []) {\n if (typeof k === \"string\" && k.length > 0) {\n set({ key: k, strategy: \"full\" });\n }\n }\n\n for (const r of rules ?? []) {\n if (typeof r === \"string\") {\n set({ key: r, strategy: \"full\" });\n continue;\n }\n const key = r.key;\n if (r.strategy === \"full\") set({ key, strategy: \"full\" });\n if (r.strategy === \"hash\") set({ key, strategy: \"hash\" });\n if (r.strategy === \"prefix\") {\n set({ key, strategy: \"prefix\", keep: typeof r.keep === \"number\" ? r.keep : 8 });\n }\n }\n\n return [...out.values()];\n}\n\nexport class Redactor {\n readonly #rules: CompiledRule[];\n\n constructor(options?: RedactorOptions) {\n this.#rules = compileRules(options?.rules, options?.extraKeys);\n }\n\n redactValue(key: string, value: unknown): unknown {\n const k = toKey(key);\n const rule = this.#rules.find((r) => r.key === k);\n if (!rule) {\n return this.#redactNested(value);\n }\n\n if (rule.strategy === \"full\") return \"[REDACTED]\";\n const asString =\n typeof value === \"string\"\n ? value\n : typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\"\n ? String(value)\n : undefined;\n\n if (rule.strategy === \"prefix\") {\n if (asString === undefined) return \"[REDACTED]\";\n const keep = Math.max(0, Math.floor(rule.keep));\n return asString.length <= keep ? `${asString}…` : `${asString.slice(0, keep)}…`;\n }\n\n if (rule.strategy === \"hash\") {\n if (asString === undefined) return \"[HASH:unknown]\";\n return `[HASH:${stableHash(asString)}]`;\n }\n\n return this.#redactNested(value);\n }\n\n redactRecord(record: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(record)) {\n out[k] = this.redactValue(k, v);\n }\n return out;\n }\n\n #redactNested(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((v) => this.#redactNested(v));\n }\n if (isRecord(value)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n out[k] = this.redactValue(k, v);\n }\n return out;\n }\n return value;\n }\n}\n\n","import type { RedactionProfile } from \"./types.js\";\n\n/** Extra keys redacted under the `share` profile (in addition to {@link DEFAULT_REDACT_KEYS}). */\nexport const SHARE_PROFILE_EXTRA_KEYS = [\n \"userEmail\",\n \"customerEmail\",\n \"phone\",\n \"phoneNumber\",\n \"address\",\n \"ip\",\n \"ipAddress\",\n \"sessionId\",\n \"requestId\",\n \"correlationId\",\n \"decisionId\",\n \"groupId\",\n \"customerId\",\n \"userId\",\n \"accountId\",\n \"tenantId\",\n \"orgId\",\n \"organizationId\",\n \"traceId\",\n \"spanId\",\n \"parentSpanId\",\n] as const;\n\n/** Extra keys redacted under the `strict` profile (in addition to share keys). */\nexport const STRICT_PROFILE_EXTRA_KEYS = [\n \"prompt\",\n \"completion\",\n \"input\",\n \"output\",\n \"inputPreview\",\n \"outputPreview\",\n \"message\",\n \"messages\",\n \"transcript\",\n \"context\",\n \"document\",\n \"documents\",\n \"chunk\",\n \"chunks\",\n \"retrieval\",\n \"query\",\n] as const;\n\nexport interface ResolvedRedactionProfile {\n profile: RedactionProfile;\n extraKeys: readonly string[];\n maxMetadataValueLengthCap?: number;\n maxPreviewLengthCap?: number;\n}\n\n/** Resolves named profile behavior (keys + metadata string caps). */\nexport function resolveRedactionProfile(\n profile: RedactionProfile = \"local\",\n): ResolvedRedactionProfile {\n switch (profile) {\n case \"local\":\n return { profile: \"local\", extraKeys: [] };\n case \"share\":\n return {\n profile: \"share\",\n extraKeys: SHARE_PROFILE_EXTRA_KEYS,\n maxMetadataValueLengthCap: 500,\n maxPreviewLengthCap: 200,\n };\n case \"strict\":\n return {\n profile: \"strict\",\n extraKeys: [...SHARE_PROFILE_EXTRA_KEYS, ...STRICT_PROFILE_EXTRA_KEYS],\n maxMetadataValueLengthCap: 200,\n maxPreviewLengthCap: 80,\n };\n default:\n return { profile: \"local\", extraKeys: [] };\n }\n}\n\nfunction isPreviewKey(key: string): boolean {\n return key.toLowerCase().includes(\"preview\");\n}\n\n/**\n * Applies profile metadata string caps. User-provided lower limits are preserved.\n */\nexport function applyProfileMetadataCaps(\n maxMetadataValueLength: number,\n maxPreviewLength: number,\n resolved: ResolvedRedactionProfile,\n): { maxMetadataValueLength: number; maxPreviewLength: number } {\n let meta = maxMetadataValueLength;\n let preview = maxPreviewLength;\n\n if (resolved.maxMetadataValueLengthCap !== undefined) {\n meta = Math.min(meta, resolved.maxMetadataValueLengthCap);\n }\n if (resolved.maxPreviewLengthCap !== undefined) {\n preview = Math.min(preview, resolved.maxPreviewLengthCap);\n }\n\n return { maxMetadataValueLength: meta, maxPreviewLength: preview };\n}\n\nexport function truncateStringForProfile(\n value: string,\n key: string,\n maxMetadataValueLength: number,\n maxPreviewLength: number,\n): string {\n const max = isPreviewKey(key) ? maxPreviewLength : maxMetadataValueLength;\n if (max <= 0) return \"…\";\n if (value.length <= max) return value;\n return `${value.slice(0, max)}…`;\n}\n","import type { RedactionRule } from \"./types/log-config.js\";\n\n/**\n * Discriminator for what kind of work a {@link Step} represents.\n * `\"decision\"` captures agent branching/choices; other values cover runs, LLM calls, tools, and user-defined steps.\n */\nexport type StepType =\n | \"run\"\n | \"llm\"\n | \"tool\"\n | \"decision\"\n | \"logic\"\n | \"state\"\n | \"custom\";\n\n/** Lifecycle state of a single {@link Step}. */\nexport type StepStatus = \"running\" | \"success\" | \"error\";\n\n/** Lifecycle state of an entire {@link Run}. */\nexport type RunStatus = \"running\" | \"success\" | \"error\";\n\n/** Structured error attached to a run or step when status is `\"error\"`. */\nexport interface ErrorInfo {\n message: string;\n stack?: string;\n}\n\n/**\n * Optional token counts for a step (e.g. LLM usage).\n * Reserved for future roadmap; MVP does not compute or persist token usage.\n */\nexport interface TokenMetadata {\n input?: number;\n output?: number;\n total?: number;\n cached?: number;\n}\n\n/** Arbitrary structured fields for a step; safe extensions use string keys. */\nexport interface StepMetadata {\n model?: string;\n toolName?: string;\n tokens?: TokenMetadata;\n retryCount?: number;\n [key: string]: unknown;\n}\n\n/**\n * One traced agent run (root of an execution tree).\n * MVP intentionally omits `input` / `output` on the run to limit PII, secrets, and serialization risk.\n */\nexport interface Run {\n id: string;\n name: string;\n status: RunStatus;\n startTime: number;\n endTime?: number;\n durationMs?: number;\n error?: ErrorInfo;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * One node in the execution tree under a {@link Run}.\n * MVP intentionally omits `input` / `output`; capture/redaction may come in a later version.\n */\nexport interface Step {\n id: string;\n runId: string;\n parentId?: string;\n name: string;\n type: StepType;\n status: StepStatus;\n startTime: number;\n endTime?: number;\n durationMs?: number;\n error?: ErrorInfo;\n metadata?: StepMetadata;\n}\n\n/** Version of the JSONL trace line schema consumed by AgentInspect tooling. */\nexport type TraceSchemaVersion = \"0.1\";\n\n/**\n * Status for lightweight trace metadata extraction.\n * `\"unknown\"` means the file contained valid events but a run status could not be determined safely.\n */\nexport type TraceMetadataStatus = \"success\" | \"error\" | \"running\" | \"unknown\";\n\nexport interface TraceMetadata {\n runId: string;\n name?: string;\n status: TraceMetadataStatus;\n startedAt?: number;\n endedAt?: number;\n durationMs?: number;\n eventCount: number;\n filePath: string;\n fileSize: number;\n createdAt: Date;\n}\n\nexport interface RunSummary {\n runId: string;\n name?: string;\n status: TraceMetadataStatus;\n durationMs?: number;\n totalSteps: number;\n llmSteps: number;\n toolSteps: number;\n logicSteps: number;\n errorSteps: number;\n maxDepth: number;\n longestStep?: {\n name: string;\n durationMs: number;\n type: string;\n };\n totalTokens?: {\n input: number;\n output: number;\n /** Present only when every token-bearing step has a supplied or derivable total. */\n total?: number;\n /** Sum of supplied cached counts; cached is not added to total. */\n cached?: number;\n };\n}\n\n/** Fields shared by every persisted trace event line. */\nexport interface TraceEventBase {\n schemaVersion: TraceSchemaVersion;\n event: string;\n timestamp: number;\n}\n\n/** Emitted when a run begins. */\nexport interface RunStartedEvent extends TraceEventBase {\n event: \"run_started\";\n runId: string;\n name: string;\n startTime: number;\n metadata?: Record<string, unknown>;\n}\n\n/** Emitted when a run finishes successfully or with an error. */\nexport interface RunCompletedEvent extends TraceEventBase {\n event: \"run_completed\";\n runId: string;\n status: \"success\" | \"error\";\n endTime: number;\n durationMs: number;\n error?: ErrorInfo;\n}\n\n/** Emitted when a step begins (including nested steps under `parentId`). */\nexport interface StepStartedEvent extends TraceEventBase {\n event: \"step_started\";\n runId: string;\n stepId: string;\n parentId?: string;\n name: string;\n type: StepType;\n startTime: number;\n metadata?: StepMetadata;\n}\n\n/**\n * Emitted when a step finishes (success or failure).\n * Failures use `status: \"error\"` and optional {@link ErrorInfo}; there is no separate `step_failed` event in MVP.\n */\nexport interface StepCompletedEvent extends TraceEventBase {\n event: \"step_completed\";\n runId: string;\n stepId: string;\n status: \"success\" | \"error\";\n endTime: number;\n durationMs: number;\n error?: ErrorInfo;\n}\n\n/** Emitted when an external-world outcome is observed (v4.4+). */\nexport interface OutcomeObservedEvent extends TraceEventBase {\n event: \"outcome_observed\";\n runId: string;\n outcomeId: string;\n parentId?: string;\n name: string;\n expectation: string;\n status: \"passed\" | \"failed\" | \"unknown\" | \"skipped\";\n method?:\n | \"dom\"\n | \"accessibility\"\n | \"snapshot\"\n | \"network\"\n | \"storage\"\n | \"filesystem\"\n | \"database\"\n | \"queue\"\n | \"custom\";\n actual?: unknown;\n evidence?: unknown;\n observedAt: number;\n}\n\n/** Discriminated union of all MVP trace events written as JSONL lines. */\nexport type TraceEvent =\n | RunStartedEvent\n | RunCompletedEvent\n | StepStartedEvent\n | StepCompletedEvent\n | OutcomeObservedEvent;\n\n/** Named redaction presets for trace writing and share-safe exports (v1.3.0+). */\nexport type RedactionProfile = \"local\" | \"share\" | \"strict\";\n\n/** Optional correlation fields for grouping and cross-run tracing (v1.3.0+). */\nexport interface TraceCorrelationMetadata {\n correlationId?: string;\n requestId?: string;\n decisionId?: string;\n groupId?: string;\n}\n\n/** Options for `inspectRun()` and `maybeInspectRun()`. */\nexport interface InspectRunOptions extends TraceCorrelationMetadata {\n traceDir?: string;\n silent?: boolean;\n metadata?: Record<string, unknown>;\n /**\n * When `false`, runs `fn` with no trace file, no execution context, and no terminal output.\n * Omitted or `true` preserves default tracing behavior.\n */\n enabled?: boolean;\n /**\n * Redact sensitive metadata keys before writing JSONL. Default `true` (conservative keys).\n * Pass `false` to persist metadata as-is (explicit opt-out).\n */\n redact?: boolean | { rules?: RedactionRule[] };\n /**\n * Redaction preset for trace metadata. Default `local` (same keys as default redaction).\n * `share` and `strict` add extra key-based redaction and tighter string bounds.\n * Ignored when `redact: false`.\n */\n redactionProfile?: RedactionProfile;\n /** Max UTF-8 bytes for a serialized trace event line. Default 65536. */\n maxEventBytes?: number;\n /** Max length for string metadata values (non-preview keys). Default 2000. */\n maxMetadataValueLength?: number;\n /** Max length for preview-like metadata keys (contains `preview`). Default 500. */\n maxPreviewLength?: number;\n}\n\n/** Options passed when opening a logical step (implemented in a later step). */\nexport interface StepOptions {\n type?: StepType;\n metadata?: StepMetadata;\n}\n\n/** Options for `observe()` — same surface as {@link InspectRunOptions} in MVP. */\nexport type ObserveOptions = InspectRunOptions;\n\n/**\n * Resolved settings for the active run while tracing is enabled.\n * Populated by runtime code in a later step; defined here for `context.ts`.\n */\nexport interface ExecutionContext {\n runId: string;\n runName: string;\n traceDir: string;\n silent: boolean;\n metadata?: Record<string, unknown>;\n}\n\n/** Stack position of the step currently executing (used by future context tracking). */\nexport interface ActiveStepContext {\n stepId: string;\n parentId?: string;\n depth: number;\n}\n\nconst STEP_TYPES: readonly StepType[] = [\n \"run\",\n \"llm\",\n \"tool\",\n \"decision\",\n \"logic\",\n \"state\",\n \"custom\",\n] as const;\n\nconst STEP_STATUSES: readonly StepStatus[] = [\n \"running\",\n \"success\",\n \"error\",\n] as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Returns true if `value` is one of the MVP {@link StepType} literals. */\nexport function isStepType(value: unknown): value is StepType {\n return (\n typeof value === \"string\" &&\n (STEP_TYPES as readonly string[]).includes(value)\n );\n}\n\n/** Returns true if `value` is one of the MVP {@link StepStatus} literals. */\nexport function isStepStatus(value: unknown): value is StepStatus {\n return (\n typeof value === \"string\" &&\n (STEP_STATUSES as readonly string[]).includes(value)\n );\n}\n\n/**\n * Narrowing guard for a {@link TraceEvent} object with required MVP fields.\n * Does not deeply validate optional `metadata` shapes.\n */\nexport function isTraceEvent(value: unknown): value is TraceEvent {\n if (!isRecord(value)) return false;\n if (value.schemaVersion !== \"0.1\") return false;\n if (typeof value.timestamp !== \"number\") return false;\n if (typeof value.event !== \"string\") return false;\n\n switch (value.event) {\n case \"run_started\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.name === \"string\" &&\n typeof value.startTime === \"number\"\n );\n }\n case \"run_completed\": {\n return (\n typeof value.runId === \"string\" &&\n (value.status === \"success\" || value.status === \"error\") &&\n typeof value.endTime === \"number\" &&\n typeof value.durationMs === \"number\"\n );\n }\n case \"step_started\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.stepId === \"string\" &&\n typeof value.name === \"string\" &&\n isStepType(value.type) &&\n typeof value.startTime === \"number\"\n );\n }\n case \"step_completed\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.stepId === \"string\" &&\n (value.status === \"success\" || value.status === \"error\") &&\n typeof value.endTime === \"number\" &&\n typeof value.durationMs === \"number\"\n );\n }\n case \"outcome_observed\": {\n return (\n typeof value.runId === \"string\" &&\n typeof value.outcomeId === \"string\" &&\n typeof value.name === \"string\" &&\n typeof value.expectation === \"string\" &&\n (value.status === \"passed\" ||\n value.status === \"failed\" ||\n value.status === \"unknown\" ||\n value.status === \"skipped\") &&\n typeof value.observedAt === \"number\"\n );\n }\n default:\n return false;\n }\n}\n","/**\n * v0.2 shared duration utilities.\n *\n * `parseDuration` is used for filters such as \"since\" / \"older-than\".\n * `formatDuration` is used for compact display in CLI and summaries.\n */\n\nexport function parseDuration(duration: string): number {\n const raw = typeof duration === \"string\" ? duration.trim() : \"\";\n const match = raw.match(/^(\\d+)(ms|[smhd])$/);\n if (!match) {\n throw new Error(\n `Invalid duration format: ${duration}. Use a positive integer followed by ms, s, m, h, or d (e.g. 500ms, 30s, 5m, 2h, 7d).`,\n );\n }\n\n const amount = Number.parseInt(match[1], 10);\n const unit = match[2];\n\n if (!Number.isFinite(amount) || amount <= 0) {\n throw new Error(\n `Invalid duration amount: ${duration}. Amount must be a positive integer.`,\n );\n }\n\n switch (unit) {\n case \"ms\":\n return amount;\n case \"s\":\n return amount * 1000;\n case \"m\":\n return amount * 60 * 1000;\n case \"h\":\n return amount * 60 * 60 * 1000;\n case \"d\":\n return amount * 24 * 60 * 60 * 1000;\n default: {\n // Should be unreachable due to regex.\n throw new Error(`Unknown duration unit: ${unit}`);\n }\n }\n}\n\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms)) {\n return \"0ms\";\n }\n if (ms < 0) {\n throw new Error(`formatDuration: ms must be non-negative (got ${ms})`);\n }\n if (ms < 1000) {\n return `${Math.floor(ms)}ms`;\n }\n if (ms < 60_000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n if (ms < 3_600_000) {\n return `${(ms / 60_000).toFixed(1)}m`;\n }\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\n","import { mkdir } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nimport { nanoid } from \"nanoid\";\n\nimport type { ErrorInfo } from \"./types.js\";\nimport { formatDuration as formatDurationV2 } from \"./utils/duration.js\";\n\n/** Default folder under the user home for AgentInspect data. */\nexport const DEFAULT_TRACE_DIR_NAME = \".agent-inspect\";\n\n/** Subfolder where JSONL run traces are stored. */\nexport const RUNS_DIR_NAME = \"runs\";\n\n/** Writable trace root when the default home path cannot be used. */\nexport const FALLBACK_TRACE_DIR = path.join(\n os.tmpdir(),\n \"agent-inspect\",\n RUNS_DIR_NAME,\n);\n\n/** Maximum display length for run/step names before truncation. */\nexport const MAX_NAME_LENGTH = 100;\n\n/** Returns `run_` + a 10-character nanoid segment. */\nexport function createRunId(): string {\n return `run_${nanoid(10)}`;\n}\n\n/** Returns `step_` + a 10-character nanoid segment. */\nexport function createStepId(): string {\n return `step_${nanoid(10)}`;\n}\n\n/** Formats a duration for CLI display (v0.2 rules). */\nexport function formatDuration(ms: number): string {\n return formatDurationV2(ms);\n}\n\n/**\n * Formats a Unix timestamp (ms) as local `YYYY-MM-DD HH:mm:ss`.\n * Invalid values yield `\"Invalid date\"` (no throw).\n */\nexport function formatTimestamp(timestamp: number): string {\n if (!Number.isFinite(timestamp)) {\n return \"Invalid date\";\n }\n const d = new Date(timestamp);\n if (Number.isNaN(d.getTime())) {\n return \"Invalid date\";\n }\n const y = d.getFullYear();\n const mo = String(d.getMonth() + 1).padStart(2, \"0\");\n const day = String(d.getDate()).padStart(2, \"0\");\n const h = String(d.getHours()).padStart(2, \"0\");\n const min = String(d.getMinutes()).padStart(2, \"0\");\n const s = String(d.getSeconds()).padStart(2, \"0\");\n return `${y}-${mo}-${day} ${h}:${min}:${s}`;\n}\n\n/**\n * Default directory for trace files: `~/DEFAULT_TRACE_DIR_NAME/RUNS_DIR_NAME`.\n * Falls back to {@link FALLBACK_TRACE_DIR} when home cannot be resolved.\n */\nexport function getDefaultTraceDir(): string {\n const envDir = process.env.AGENT_INSPECT_TRACE_DIR;\n if (typeof envDir === \"string\" && envDir.trim() !== \"\") {\n return envDir.trim();\n }\n try {\n const home = os.homedir();\n if (typeof home !== \"string\" || home.trim() === \"\") {\n return FALLBACK_TRACE_DIR;\n }\n return path.join(home, DEFAULT_TRACE_DIR_NAME, RUNS_DIR_NAME);\n } catch {\n return FALLBACK_TRACE_DIR;\n }\n}\n\n/**\n * Full path to the JSONL trace file for a run.\n * `runId` is passed through `path.basename` to avoid traversal; empty ids become `run_unknown`.\n */\nexport function getTraceFilePath(runId: string, traceDir?: string): string {\n const baseDir = traceDir ?? getDefaultTraceDir();\n let safeId =\n typeof runId === \"string\" && runId.trim() !== \"\" ? runId.trim() : \"run_unknown\";\n safeId = path.basename(safeId);\n if (safeId === \"\" || safeId === \".\" || safeId === \"..\") {\n safeId = \"run_unknown\";\n }\n return path.join(baseDir, `${safeId}.jsonl`);\n}\n\n/**\n * Ensures a trace directory exists (recursive). Tries {@link FALLBACK_TRACE_DIR} on failure.\n * Returns the directory path that callers should prefer: primary, fallback, or original if both mkdir attempts fail.\n * Emits concise `[AgentInspect]` warnings on failure; never throws.\n */\nexport async function ensureTraceDir(traceDir: string): Promise<string> {\n const primary = path.resolve(traceDir);\n try {\n await mkdir(primary, { recursive: true });\n return primary;\n } catch {\n warn(`Failed to create trace directory: ${primary}`);\n const fallback = path.resolve(FALLBACK_TRACE_DIR);\n try {\n await mkdir(fallback, { recursive: true });\n return fallback;\n } catch {\n warn(`Failed to create fallback trace directory: ${fallback}`);\n return primary;\n }\n }\n}\n\n/**\n * Normalizes any thrown/caught value into {@link ErrorInfo}.\n * Never throws (circular structures and non-JSON values fall back to a generic message).\n */\nexport function formatError(error: unknown): ErrorInfo {\n if (error instanceof Error) {\n const out: ErrorInfo = { message: error.message };\n if (typeof error.stack === \"string\" && error.stack.length > 0) {\n out.stack = error.stack;\n }\n return out;\n }\n if (typeof error === \"string\") {\n return { message: error };\n }\n if (error === null) {\n return { message: \"Unknown error: null\" };\n }\n if (error === undefined) {\n return { message: \"Unknown error: undefined\" };\n }\n if (\n typeof error === \"number\" ||\n typeof error === \"boolean\" ||\n typeof error === \"bigint\"\n ) {\n return { message: String(error) };\n }\n if (typeof error === \"object\") {\n try {\n return { message: JSON.stringify(error) };\n } catch {\n return { message: \"Unknown error\" };\n }\n }\n return { message: \"Unknown error\" };\n}\n\n/**\n * Truncates a display name to `maxLength`, appending `\"...\"` when shortened.\n * Empty or non-string input becomes `\"unnamed\"`.\n */\nexport function truncateName(name: string, maxLength = MAX_NAME_LENGTH): string {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n return \"unnamed\";\n }\n const trimmed = name.trim();\n if (trimmed.length <= maxLength) {\n return trimmed;\n }\n const ellipsis = \"...\";\n const head = Math.max(0, maxLength - ellipsis.length);\n return `${trimmed.slice(0, head)}${ellipsis}`;\n}\n\n/**\n * Instrumentation-only warning to stderr. Not a general-purpose logger.\n * Optional `error` is summarized via {@link formatError} (message only).\n */\nexport function warn(message: string, error?: unknown): void {\n const base = `[AgentInspect] ${message}`;\n if (error === undefined) {\n console.warn(base);\n return;\n }\n console.warn(`${base}: ${formatError(error).message}`);\n}\n","import { appendFile, readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { TraceEvent } from \"./types.js\";\nimport { isStepType } from \"./types.js\";\nimport {\n DEFAULT_MAX_EVENT_BYTES,\n prepareTraceEventForDisk,\n resolveTraceSafetyOptions,\n} from \"./trace-event-safety.js\";\nimport { parseTraceJsonl } from \"./read-trace.js\";\nimport {\n ensureTraceDir,\n FALLBACK_TRACE_DIR,\n getTraceFilePath,\n warn,\n} from \"./utils.js\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction nonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim() !== \"\";\n}\n\nfunction finiteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction optionalErrorInfo(value: unknown): boolean {\n if (value === undefined) return true;\n if (!isRecord(value)) return false;\n if (typeof value.message !== \"string\") return false;\n if (\"stack\" in value && value.stack !== undefined) {\n if (typeof value.stack !== \"string\") return false;\n }\n return true;\n}\n\n/**\n * Strict MVP validation before writing JSONL. Rejects empty ids, non-finite times, and malformed payloads.\n */\nexport function validateEvent(event: unknown): event is TraceEvent {\n if (!isRecord(event)) return false;\n if (event.schemaVersion !== \"0.1\") return false;\n if (!finiteNumber(event.timestamp)) return false;\n if (typeof event.event !== \"string\") return false;\n\n switch (event.event) {\n case \"run_started\": {\n if (\n !nonEmptyString(event.runId) ||\n !nonEmptyString(event.name) ||\n !finiteNumber(event.startTime)\n ) {\n return false;\n }\n if (event.metadata !== undefined && !isRecord(event.metadata)) {\n return false;\n }\n return true;\n }\n case \"run_completed\": {\n return (\n nonEmptyString(event.runId) &&\n (event.status === \"success\" || event.status === \"error\") &&\n finiteNumber(event.endTime) &&\n finiteNumber(event.durationMs) &&\n optionalErrorInfo(event.error)\n );\n }\n case \"step_started\": {\n if (\n !nonEmptyString(event.runId) ||\n !nonEmptyString(event.stepId) ||\n !nonEmptyString(event.name) ||\n !isStepType(event.type) ||\n !finiteNumber(event.startTime)\n ) {\n return false;\n }\n if (event.parentId !== undefined && typeof event.parentId !== \"string\") {\n return false;\n }\n if (event.metadata !== undefined && !isRecord(event.metadata)) {\n return false;\n }\n return true;\n }\n case \"step_completed\": {\n return (\n nonEmptyString(event.runId) &&\n nonEmptyString(event.stepId) &&\n (event.status === \"success\" || event.status === \"error\") &&\n finiteNumber(event.endTime) &&\n finiteNumber(event.durationMs) &&\n optionalErrorInfo(event.error)\n );\n }\n case \"outcome_observed\": {\n return (\n nonEmptyString(event.runId) &&\n nonEmptyString(event.outcomeId) &&\n nonEmptyString(event.name) &&\n nonEmptyString(event.expectation) &&\n (event.status === \"passed\" ||\n event.status === \"failed\" ||\n event.status === \"unknown\" ||\n event.status === \"skipped\") &&\n finiteNumber(event.observedAt)\n );\n }\n default:\n return false;\n }\n}\n\n/** Serializes a trace line as compact JSON without a trailing newline. */\nexport function serializeEvent(event: TraceEvent): string {\n try {\n return JSON.stringify(event);\n } catch {\n return \"\";\n }\n}\n\n/**\n * Creates (or truncates) an empty JSONL file for a run. Uses {@link ensureTraceDir} then {@link getTraceFilePath}.\n * On failure, retries once under {@link FALLBACK_TRACE_DIR}.\n */\nexport async function initializeTraceFile(\n runId: string,\n traceDir: string,\n): Promise<string | undefined> {\n try {\n const usable = await ensureTraceDir(traceDir);\n const filePath = getTraceFilePath(runId, usable);\n await writeFile(filePath, \"\", \"utf-8\");\n return filePath;\n } catch (e) {\n warn(\"Failed to initialize trace file\", e);\n }\n\n try {\n const usable = await ensureTraceDir(FALLBACK_TRACE_DIR);\n const filePath = getTraceFilePath(runId, usable);\n await writeFile(filePath, \"\", \"utf-8\");\n return filePath;\n } catch (e) {\n warn(\"Failed to initialize trace file on fallback directory\", e);\n return undefined;\n }\n}\n\n/**\n * Appends one validated JSONL line for `event.runId`. Falls back to {@link FALLBACK_TRACE_DIR} on append failure.\n */\nfunction ensureEventWithinBounds(event: TraceEvent): TraceEvent {\n const line = serializeEvent(event);\n if (line === \"\") return event;\n const bytes = Buffer.byteLength(line, \"utf8\");\n if (bytes <= DEFAULT_MAX_EVENT_BYTES) return event;\n return prepareTraceEventForDisk(event, resolveTraceSafetyOptions());\n}\n\nexport async function writeTraceEvent(\n event: TraceEvent,\n traceDir: string,\n): Promise<void> {\n const bounded = ensureEventWithinBounds(event);\n\n if (!validateEvent(bounded)) {\n warn(\"Skipped invalid trace event (validation failed)\");\n return;\n }\n\n const line = serializeEvent(bounded);\n if (line === \"\") {\n warn(\"Skipped trace event (serialization failed)\");\n return;\n }\n\n const payload = `${line}\\n`;\n\n const tryAppend = async (dir: string): Promise<boolean> => {\n try {\n const usable = await ensureTraceDir(dir);\n const filePath = getTraceFilePath(event.runId, usable);\n await appendFile(filePath, payload, \"utf-8\");\n return true;\n } catch {\n return false;\n }\n };\n\n if (await tryAppend(traceDir)) {\n return;\n }\n\n warn(`Failed to append trace event for run ${event.runId}`);\n\n if (await tryAppend(FALLBACK_TRACE_DIR)) {\n return;\n }\n\n warn(\"Failed to append trace event to fallback directory\");\n}\n\n/**\n * Reads raw JSONL file contents for a run, or `undefined` if missing or unreadable.\n */\nexport async function readTraceFile(\n runId: string,\n traceDir: string,\n): Promise<string | undefined> {\n try {\n const filePath = getTraceFilePath(runId, traceDir);\n return await readFile(filePath, \"utf-8\");\n } catch (e) {\n if (e && typeof e === \"object\" && \"code\" in e && e.code === \"ENOENT\") {\n return undefined;\n }\n warn(\"Unexpected error reading trace file\", e);\n return undefined;\n }\n}\n\n/**\n * Parses JSONL into validated {@link TraceEvent} rows (v0.1 native or v0.2 normalized).\n * Invalid lines are skipped with a warning.\n */\nexport async function readTraceEvents(\n runId: string,\n traceDir: string,\n): Promise<TraceEvent[]> {\n try {\n const filePath = getTraceFilePath(runId, traceDir);\n return await readTraceEventsFromFile(filePath);\n } catch (e) {\n warn(\"Failed to read trace events\", e);\n return [];\n }\n}\n\n/**\n * Reads and normalizes trace events from an exact file path.\n * Used by directory scans where the embedded run id may differ from the basename.\n */\nexport async function readTraceEventsFromFile(\n filePath: string,\n): Promise<TraceEvent[]> {\n try {\n const raw = await readFile(filePath, \"utf-8\");\n return parseTraceJsonl(raw, { validate: validateEvent }).events;\n } catch (e) {\n if (e && typeof e === \"object\" && \"code\" in e && e.code === \"ENOENT\") {\n return [];\n }\n warn(\"Failed to read trace events from file\", e);\n return [];\n }\n}\n\n/**\n * Lists `.jsonl` file names in `traceDir`, newest by mtime first (name sort as tie-breaker).\n */\nexport async function listTraceFiles(traceDir: string): Promise<string[]> {\n try {\n const usable = path.resolve(traceDir);\n const names = await readdir(usable);\n const jsonl = names.filter((n) => n.endsWith(\".jsonl\"));\n const withStat = await Promise.all(\n jsonl.map(async (name) => {\n try {\n const st = await stat(path.join(usable, name));\n return { name, mtime: st.mtimeMs };\n } catch {\n return { name, mtime: 0 };\n }\n }),\n );\n withStat.sort((a, b) => {\n if (b.mtime !== a.mtime) return b.mtime - a.mtime;\n return a.name.localeCompare(b.name);\n });\n return withStat.map((x) => x.name);\n } catch {\n return [];\n }\n}\n\n/** Maps a `.jsonl` file name to its run id (basename only; no traversal). */\nexport function getRunIdFromTraceFileName(fileName: string): string | undefined {\n try {\n const base = path.basename(fileName);\n if (!base.endsWith(\".jsonl\")) return undefined;\n const id = base.slice(0, -\".jsonl\".length);\n return id === \"\" ? undefined : id;\n } catch {\n return undefined;\n }\n}\n","import { Redactor } from \"./logs/redactor.js\";\nimport {\n applyProfileMetadataCaps,\n resolveRedactionProfile,\n type ResolvedRedactionProfile,\n} from \"./redaction-profiles.js\";\nimport { serializeEvent } from \"./storage.js\";\nimport type { RedactionRule } from \"./types/log-config.js\";\nimport {\n isPersistedInspectEvent,\n type PersistedInspectError,\n type PersistedInspectEvent,\n type PersistedTokenUsage,\n type PersistedTraceContext,\n} from \"./types/persisted-inspect-event.js\";\nimport type {\n InspectRunOptions,\n RedactionProfile,\n StepMetadata,\n TraceEvent,\n} from \"./types.js\";\n\n/** Default max length for string metadata values (non-preview keys). */\nexport const DEFAULT_MAX_METADATA_VALUE_LENGTH = 2000;\n\n/** Default max length for preview-like metadata keys (contains `preview`, case-insensitive). */\nexport const DEFAULT_MAX_PREVIEW_LENGTH = 500;\n\n/** Default max serialized JSONL line size in bytes (UTF-8). */\nexport const DEFAULT_MAX_EVENT_BYTES = 65_536;\n\n/** Resolved trace safety settings used at write time. */\nexport interface TraceSafetyOptions {\n redactEnabled: boolean;\n redactionRules?: RedactionRule[];\n redactionProfile: RedactionProfile;\n profileExtraKeys: readonly string[];\n maxMetadataValueLength: number;\n maxPreviewLength: number;\n maxEventBytes: number;\n}\n\nexport type { ResolvedRedactionProfile };\nexport { resolveRedactionProfile };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nconst KNOWN_PERSISTED_EVENT_FIELDS = new Set([\n \"schemaVersion\",\n \"eventId\",\n \"runId\",\n \"kind\",\n \"name\",\n \"parentId\",\n \"status\",\n \"timestamp\",\n \"startedAt\",\n \"endedAt\",\n \"durationMs\",\n \"confidence\",\n \"source\",\n \"attributes\",\n \"inputSummary\",\n \"outputSummary\",\n \"error\",\n \"tokenUsage\",\n \"trace\",\n]);\n\nfunction isSafeExtensionFieldName(key: string): boolean {\n return key !== \"__proto__\" && key !== \"constructor\" && key !== \"prototype\";\n}\n\nfunction isPreviewKey(key: string): boolean {\n return key.toLowerCase().includes(\"preview\");\n}\n\nfunction truncateString(value: string, maxLen: number): string {\n if (maxLen <= 0) return \"…\";\n if (value.length <= maxLen) return value;\n return `${value.slice(0, maxLen)}…`;\n}\n\nfunction byteLength(text: string): number {\n return Buffer.byteLength(text, \"utf8\");\n}\n\n/** Resolves {@link InspectRunOptions} trace safety fields with safe defaults. */\nexport function resolveTraceSafetyOptions(\n options?: Pick<\n InspectRunOptions,\n | \"redact\"\n | \"redactionProfile\"\n | \"maxEventBytes\"\n | \"maxMetadataValueLength\"\n | \"maxPreviewLength\"\n >,\n): TraceSafetyOptions {\n const redact = options?.redact;\n let redactEnabled = true;\n let redactionRules: RedactionRule[] | undefined;\n\n if (redact === false) {\n redactEnabled = false;\n } else if (redact === true || redact === undefined) {\n redactEnabled = true;\n } else if (isRecord(redact)) {\n redactEnabled = true;\n redactionRules = redact.rules;\n }\n\n const profile = options?.redactionProfile ?? \"local\";\n const resolvedProfile = resolveRedactionProfile(profile);\n\n const userMaxMetadata =\n typeof options?.maxMetadataValueLength === \"number\" &&\n Number.isFinite(options.maxMetadataValueLength) &&\n options.maxMetadataValueLength >= 0\n ? Math.floor(options.maxMetadataValueLength)\n : undefined;\n const userMaxPreview =\n typeof options?.maxPreviewLength === \"number\" &&\n Number.isFinite(options.maxPreviewLength) &&\n options.maxPreviewLength >= 0\n ? Math.floor(options.maxPreviewLength)\n : undefined;\n\n let maxMetadataValueLength = userMaxMetadata ?? DEFAULT_MAX_METADATA_VALUE_LENGTH;\n let maxPreviewLength = userMaxPreview ?? DEFAULT_MAX_PREVIEW_LENGTH;\n\n if (redactEnabled && profile !== \"local\") {\n const capped = applyProfileMetadataCaps(\n maxMetadataValueLength,\n maxPreviewLength,\n resolvedProfile,\n );\n maxMetadataValueLength = capped.maxMetadataValueLength;\n maxPreviewLength = capped.maxPreviewLength;\n }\n\n return {\n redactEnabled,\n redactionRules,\n redactionProfile: profile,\n profileExtraKeys: redactEnabled ? resolvedProfile.extraKeys : [],\n maxMetadataValueLength,\n maxPreviewLength,\n maxEventBytes:\n typeof options?.maxEventBytes === \"number\" &&\n Number.isFinite(options.maxEventBytes) &&\n options.maxEventBytes > 0\n ? Math.floor(options.maxEventBytes)\n : DEFAULT_MAX_EVENT_BYTES,\n };\n}\n\nfunction boundMetadataValue(\n key: string,\n value: unknown,\n opts: TraceSafetyOptions,\n seen: WeakSet<object>,\n depth: number,\n): unknown {\n if (depth > 32) return \"[MaxDepth]\";\n\n if (typeof value === \"bigint\") {\n return `${value.toString()}n`;\n }\n if (typeof value === \"function\") {\n return \"[Function]\";\n }\n if (typeof value === \"symbol\") {\n return \"[Symbol]\";\n }\n if (typeof value === \"number\" && !Number.isFinite(value)) {\n return String(value);\n }\n if (value === undefined) {\n return null;\n }\n\n if (value === null || typeof value !== \"object\") {\n if (typeof value === \"string\") {\n const max = isPreviewKey(key) ? opts.maxPreviewLength : opts.maxMetadataValueLength;\n return truncateString(value, max);\n }\n return value;\n }\n\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n\n if (Array.isArray(value)) {\n const maxItems = 50;\n const out = value\n .slice(0, maxItems)\n .map((item, index) =>\n boundMetadataValue(String(index), item, opts, seen, depth + 1),\n );\n if (value.length > maxItems) {\n out.push(`…(+${value.length - maxItems} more)`);\n }\n return out;\n }\n\n const record = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n try {\n for (const [k, v] of Object.entries(record)) {\n out[k] = boundMetadataValue(k, v, opts, seen, depth + 1);\n }\n } catch {\n return { truncated: true, reason: \"metadataEnumerationFailed\" };\n }\n return out;\n}\n\nfunction redactMetadata(\n metadata: Record<string, unknown>,\n opts: TraceSafetyOptions,\n): Record<string, unknown> {\n if (!opts.redactEnabled) return { ...metadata };\n const redactor = new Redactor({\n rules: opts.redactionRules,\n extraKeys: opts.profileExtraKeys,\n });\n return redactor.redactRecord(metadata);\n}\n\n/** Redacts (when enabled) and truncates metadata values for disk persistence. */\nexport function prepareMetadataForDisk(\n metadata: Record<string, unknown> | StepMetadata,\n opts: TraceSafetyOptions,\n): Record<string, unknown> {\n try {\n const preBounded = boundMetadataValue(\n \"metadata\",\n metadata,\n opts,\n new WeakSet<object>(),\n 0,\n );\n const redacted = redactMetadata(\n isRecord(preBounded) ? preBounded : {},\n opts,\n );\n const bounded = boundMetadataValue(\n \"metadata\",\n redacted,\n opts,\n new WeakSet<object>(),\n 0,\n );\n return isRecord(bounded) ? bounded : {};\n } catch {\n return { truncated: true, reason: \"metadataPreparationFailed\" };\n }\n}\n\nfunction truncateErrorStack(\n event: TraceEvent,\n maxLen: number,\n): TraceEvent {\n if (event.event !== \"run_completed\" && event.event !== \"step_completed\") {\n return event;\n }\n if (!event.error?.stack || typeof event.error.stack !== \"string\") {\n return event;\n }\n return {\n ...event,\n error: {\n ...event.error,\n stack: truncateString(event.error.stack, maxLen),\n },\n };\n}\n\nfunction replaceMetadataWithTruncationMarker(\n event: TraceEvent,\n originalApproxBytes: number,\n): TraceEvent {\n const marker = {\n truncated: true,\n reason: \"maxEventBytes\",\n originalApproxBytes,\n };\n if (event.event === \"run_started\") {\n return { ...event, metadata: marker };\n }\n if (event.event === \"step_started\") {\n return { ...event, metadata: marker };\n }\n return event;\n}\n\nfunction shrinkMetadataLimits(\n opts: TraceSafetyOptions,\n factor: number,\n): TraceSafetyOptions {\n return {\n ...opts,\n maxMetadataValueLength: Math.max(32, Math.floor(opts.maxMetadataValueLength * factor)),\n maxPreviewLength: Math.max(16, Math.floor(opts.maxPreviewLength * factor)),\n };\n}\n\nfunction applyMetadataToEvent(\n event: TraceEvent,\n metadata: Record<string, unknown>,\n): TraceEvent {\n if (event.event === \"run_started\") {\n return { ...event, metadata };\n }\n if (event.event === \"step_started\") {\n return { ...event, metadata: metadata as StepMetadata };\n }\n return event;\n}\n\nfunction eventHasMetadata(event: TraceEvent): boolean {\n return (\n (event.event === \"run_started\" || event.event === \"step_started\") &&\n event.metadata !== undefined\n );\n}\n\nfunction getEventMetadata(event: TraceEvent): Record<string, unknown> | undefined {\n if (event.event === \"run_started\" || event.event === \"step_started\") {\n return event.metadata as Record<string, unknown> | undefined;\n }\n return undefined;\n}\n\n/**\n * Applies redaction, metadata truncation, and final serialized size bounds.\n * Never throws; returns a schema-valid event or a minimally truncated variant.\n */\nexport function prepareTraceEventForDisk(\n event: TraceEvent,\n opts: TraceSafetyOptions,\n): TraceEvent {\n try {\n let working: TraceEvent = { ...event };\n\n const rawMetadata = getEventMetadata(working);\n if (rawMetadata !== undefined) {\n const safe = prepareMetadataForDisk(rawMetadata, opts);\n working = applyMetadataToEvent(working, safe);\n }\n\n let serialized = serializeEvent(working);\n if (serialized === \"\") {\n return working;\n }\n\n let bytes = byteLength(serialized);\n if (bytes <= opts.maxEventBytes) {\n return working;\n }\n\n if (rawMetadata !== undefined) {\n for (const factor of [0.5, 0.25, 0.1]) {\n const tighter = shrinkMetadataLimits(opts, factor);\n const shrunk = prepareMetadataForDisk(rawMetadata, tighter);\n working = applyMetadataToEvent(working, shrunk);\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n }\n\n working = replaceMetadataWithTruncationMarker(working, bytes);\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n }\n\n working = truncateErrorStack(working, Math.min(opts.maxMetadataValueLength, 500));\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n\n if (eventHasMetadata(working)) {\n working = replaceMetadataWithTruncationMarker(working, bytes);\n serialized = serializeEvent(working);\n if (serialized !== \"\" && byteLength(serialized) <= opts.maxEventBytes) {\n return working;\n }\n\n if (working.event === \"run_started\") {\n const { metadata: _meta, ...rest } = working;\n working = rest;\n } else if (working.event === \"step_started\") {\n const { metadata: _meta, ...rest } = working;\n working = rest;\n }\n }\n\n return working;\n } catch {\n if (event.event === \"run_started\" || event.event === \"step_started\") {\n return applyMetadataToEvent(event, {\n truncated: true,\n reason: \"prepareTraceEventFailed\",\n });\n }\n return event;\n }\n}\n\nfunction safeGet(record: Record<string, unknown>, key: string): unknown {\n try {\n return record[key];\n } catch {\n return undefined;\n }\n}\n\nfunction optionalBoundedString(\n value: unknown,\n _key: string,\n opts: TraceSafetyOptions,\n): string | undefined {\n if (typeof value !== \"string\") return undefined;\n return truncateString(value, opts.maxMetadataValueLength);\n}\n\nfunction requiredBoundedString(\n value: unknown,\n key: string,\n opts: TraceSafetyOptions,\n): string | undefined {\n const out = optionalBoundedString(value, key, opts);\n return out && out.length > 0 ? out : undefined;\n}\n\nfunction preparePersistedSummaryForDisk(\n key: \"input\" | \"output\",\n value: unknown,\n opts: TraceSafetyOptions,\n): unknown {\n try {\n const redactor = new Redactor({\n rules: opts.redactionRules,\n extraKeys: opts.profileExtraKeys,\n });\n const redacted = opts.redactEnabled ? redactor.redactValue(key, value) : value;\n return boundMetadataValue(key, redacted, opts, new WeakSet<object>(), 0);\n } catch {\n return { truncated: true, reason: \"summaryPreparationFailed\" };\n }\n}\n\nfunction preparePersistedErrorForDisk(\n value: unknown,\n opts: TraceSafetyOptions,\n): PersistedInspectError | undefined {\n if (!isRecord(value)) return undefined;\n\n try {\n const redactor = new Redactor({\n rules: opts.redactionRules,\n extraKeys: opts.profileExtraKeys,\n });\n const rawMessage = safeGet(value, \"message\");\n const redactedMessage = opts.redactEnabled\n ? redactor.redactValue(\"message\", rawMessage)\n : rawMessage;\n const boundedMessage = boundMetadataValue(\n \"message\",\n redactedMessage,\n opts,\n new WeakSet<object>(),\n 0,\n );\n const message =\n typeof boundedMessage === \"string\" && boundedMessage.length > 0\n ? boundedMessage\n : \"Unknown error\";\n\n const out: PersistedInspectError = { message };\n const name = optionalBoundedString(safeGet(value, \"name\"), \"name\", opts);\n const code = optionalBoundedString(safeGet(value, \"code\"), \"code\", opts);\n if (name !== undefined) out.name = name;\n if (code !== undefined) out.code = code;\n return out;\n } catch {\n return { message: \"Error preparation failed\" };\n }\n}\n\nfunction prepareTokenUsage(value: unknown): PersistedTokenUsage | undefined {\n if (!isRecord(value)) return undefined;\n const out: PersistedTokenUsage = {};\n for (const key of [\"input\", \"output\", \"total\", \"cached\"] as const) {\n const item = safeGet(value, key);\n if (typeof item === \"number\" && Number.isFinite(item) && item >= 0) {\n out[key] = item;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction prepareTraceContext(\n value: unknown,\n opts: TraceSafetyOptions,\n): PersistedTraceContext | undefined {\n if (!isRecord(value)) return undefined;\n const out: PersistedTraceContext = {};\n const traceId = optionalBoundedString(safeGet(value, \"traceId\"), \"traceId\", opts);\n const spanId = optionalBoundedString(safeGet(value, \"spanId\"), \"spanId\", opts);\n const parentSpanId = optionalBoundedString(\n safeGet(value, \"parentSpanId\"),\n \"parentSpanId\",\n opts,\n );\n if (traceId !== undefined) out.traceId = traceId;\n if (spanId !== undefined) out.spanId = spanId;\n if (parentSpanId !== undefined) out.parentSpanId = parentSpanId;\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction preparePersistedExtensionFieldForDisk(\n key: string,\n value: unknown,\n opts: TraceSafetyOptions,\n): unknown {\n if (isRecord(value)) {\n return prepareMetadataForDisk(value, opts);\n }\n\n const prepared = prepareMetadataForDisk({ [key]: value }, opts);\n return Object.prototype.hasOwnProperty.call(prepared, key)\n ? prepared[key]\n : undefined;\n}\n\nfunction preserveV10ExtensionFields(\n source: Record<string, unknown>,\n candidate: PersistedInspectEvent,\n opts: TraceSafetyOptions,\n): void {\n if (candidate.schemaVersion !== \"1.0\") return;\n\n for (const [key, value] of Object.entries(source)) {\n if (\n KNOWN_PERSISTED_EVENT_FIELDS.has(key) ||\n !isSafeExtensionFieldName(key)\n ) {\n continue;\n }\n\n const prepared = preparePersistedExtensionFieldForDisk(key, value, opts);\n if (prepared !== undefined) {\n candidate[key] = prepared;\n }\n }\n}\n\nfunction serializedPersistedEvent(event: PersistedInspectEvent): string | undefined {\n try {\n return JSON.stringify(event);\n } catch {\n return undefined;\n }\n}\n\nfunction persistedEventByteLength(event: PersistedInspectEvent): number | undefined {\n const serialized = serializedPersistedEvent(event);\n return serialized === undefined ? undefined : byteLength(serialized);\n}\n\nfunction minimalPersistedEvent(\n event: PersistedInspectEvent,\n opts: TraceSafetyOptions,\n originalApproxBytes: number,\n): PersistedInspectEvent {\n return {\n schemaVersion: event.schemaVersion,\n eventId: truncateString(event.eventId, 128),\n runId: truncateString(event.runId, 128),\n kind: event.kind,\n name: truncateString(event.name, 128),\n ...(event.status !== undefined ? { status: event.status } : {}),\n timestamp: truncateString(event.timestamp, 128),\n confidence: event.confidence,\n source: {\n type: event.source.type,\n ...(event.source.name !== undefined\n ? { name: truncateString(event.source.name, 128) }\n : {}),\n ...(event.source.version !== undefined\n ? { version: truncateString(event.source.version, 128) }\n : {}),\n },\n attributes: {\n truncated: true,\n reason: \"maxEventBytes\",\n originalApproxBytes,\n maxEventBytes: opts.maxEventBytes,\n },\n };\n}\n\nfunction tinyPersistedEvent(event: PersistedInspectEvent): PersistedInspectEvent {\n return {\n schemaVersion: event.schemaVersion,\n eventId: truncateString(event.eventId, 32),\n runId: truncateString(event.runId, 32),\n kind: event.kind,\n name: truncateString(event.name, 32),\n timestamp: truncateString(event.timestamp, 32),\n confidence: event.confidence,\n source: { type: event.source.type },\n attributes: { truncated: true, reason: \"maxEventBytes\" },\n };\n}\n\nfunction enforcePersistedEventSize(\n event: PersistedInspectEvent,\n opts: TraceSafetyOptions,\n): PersistedInspectEvent | undefined {\n const bytes = persistedEventByteLength(event);\n if (bytes === undefined) return undefined;\n if (bytes <= opts.maxEventBytes) return event;\n\n const minimal = minimalPersistedEvent(event, opts, bytes);\n const minimalBytes = persistedEventByteLength(minimal);\n if (minimalBytes !== undefined && minimalBytes <= opts.maxEventBytes) {\n return minimal;\n }\n\n const tiny = tinyPersistedEvent(event);\n return isPersistedInspectEvent(tiny) ? tiny : undefined;\n}\n\n/**\n * Prepares persisted inspect events for built-in persistence.\n *\n * The helper is intentionally non-throwing: invalid required fields return\n * `undefined`; supported optional fields are redacted, bounded, JSON-safe, and\n * final serialized-size checked before a writer sees the event.\n */\nexport function preparePersistedInspectEventForWrite(\n value: unknown,\n opts: TraceSafetyOptions = resolveTraceSafetyOptions(),\n): PersistedInspectEvent | undefined {\n try {\n if (!isRecord(value)) return undefined;\n\n const source = safeGet(value, \"source\");\n if (!isRecord(source)) return undefined;\n\n const candidate: PersistedInspectEvent = {\n schemaVersion: safeGet(value, \"schemaVersion\") as PersistedInspectEvent[\"schemaVersion\"],\n eventId: requiredBoundedString(safeGet(value, \"eventId\"), \"eventId\", opts) ?? \"\",\n runId: requiredBoundedString(safeGet(value, \"runId\"), \"runId\", opts) ?? \"\",\n kind: safeGet(value, \"kind\") as PersistedInspectEvent[\"kind\"],\n name: requiredBoundedString(safeGet(value, \"name\"), \"name\", opts) ?? \"\",\n timestamp: requiredBoundedString(safeGet(value, \"timestamp\"), \"timestamp\", opts) ?? \"\",\n confidence: safeGet(value, \"confidence\") as PersistedInspectEvent[\"confidence\"],\n source: {\n type: safeGet(source, \"type\") as PersistedInspectEvent[\"source\"][\"type\"],\n },\n };\n\n const parentId = requiredBoundedString(safeGet(value, \"parentId\"), \"parentId\", opts);\n const status = safeGet(value, \"status\");\n const startedAt = optionalBoundedString(safeGet(value, \"startedAt\"), \"startedAt\", opts);\n const endedAt = optionalBoundedString(safeGet(value, \"endedAt\"), \"endedAt\", opts);\n const durationMs = safeGet(value, \"durationMs\");\n const sourceName = optionalBoundedString(safeGet(source, \"name\"), \"name\", opts);\n const sourceVersion = optionalBoundedString(safeGet(source, \"version\"), \"version\", opts);\n\n if (parentId !== undefined) candidate.parentId = parentId;\n if (\n status === \"running\" ||\n status === \"ok\" ||\n status === \"error\" ||\n status === \"unknown\"\n ) {\n candidate.status = status;\n }\n if (startedAt !== undefined) candidate.startedAt = startedAt;\n if (endedAt !== undefined) candidate.endedAt = endedAt;\n if (\n typeof durationMs === \"number\" &&\n Number.isFinite(durationMs) &&\n durationMs >= 0\n ) {\n candidate.durationMs = durationMs;\n }\n if (sourceName !== undefined) candidate.source.name = sourceName;\n if (sourceVersion !== undefined) candidate.source.version = sourceVersion;\n\n const attributes = safeGet(value, \"attributes\");\n if (isRecord(attributes)) {\n candidate.attributes = prepareMetadataForDisk(attributes, opts);\n }\n\n if (safeGet(value, \"inputSummary\") !== undefined) {\n candidate.inputSummary = preparePersistedSummaryForDisk(\n \"input\",\n safeGet(value, \"inputSummary\"),\n opts,\n );\n }\n if (safeGet(value, \"outputSummary\") !== undefined) {\n candidate.outputSummary = preparePersistedSummaryForDisk(\n \"output\",\n safeGet(value, \"outputSummary\"),\n opts,\n );\n }\n\n const error = preparePersistedErrorForDisk(safeGet(value, \"error\"), opts);\n if (error !== undefined) candidate.error = error;\n\n const tokenUsage = prepareTokenUsage(safeGet(value, \"tokenUsage\"));\n if (tokenUsage !== undefined) candidate.tokenUsage = tokenUsage;\n\n const trace = prepareTraceContext(safeGet(value, \"trace\"), opts);\n if (trace !== undefined) candidate.trace = trace;\n\n preserveV10ExtensionFields(value, candidate, opts);\n\n if (!isPersistedInspectEvent(candidate)) return undefined;\n return enforcePersistedEventSize(candidate, opts);\n } catch {\n return undefined;\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport { extractCorrelationMetadata } from \"./correlation-metadata.js\";\nimport type { ExecutionContext, TraceCorrelationMetadata } from \"./types.js\";\nimport {\n resolveTraceSafetyOptions,\n type TraceSafetyOptions,\n} from \"./trace-event-safety.js\";\n\ntype RuntimeExecutionContext = ExecutionContext & {\n currentStepId?: string;\n currentDepth: number;\n traceSafety: TraceSafetyOptions;\n};\n\nconst storage = new AsyncLocalStorage<RuntimeExecutionContext>();\n\nfunction toPublicContext(ctx: RuntimeExecutionContext): ExecutionContext {\n return {\n runId: ctx.runId,\n runName: ctx.runName,\n traceDir: ctx.traceDir,\n silent: ctx.silent,\n metadata: ctx.metadata,\n };\n}\n\nfunction invoke<T>(fn: () => T | Promise<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n try {\n Promise.resolve(fn()).then(resolve, reject);\n } catch (e) {\n reject(e);\n }\n });\n}\n\n/** Returns the active run context, without internal step fields. */\nexport function getCurrentContext(): ExecutionContext | undefined {\n try {\n const s = storage.getStore();\n if (!s) return undefined;\n return toPublicContext(s);\n } catch {\n return undefined;\n }\n}\n\n/** Active `runId` when inside `runWithContext`, else `undefined`. */\nexport function getCurrentRunId(): string | undefined {\n try {\n return storage.getStore()?.runId;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Correlation metadata for the active run (`correlationId`, `requestId`, `decisionId`, `groupId`).\n * `undefined` outside `inspectRun` / `maybeInspectRun` or when no correlation fields were set.\n */\nexport function getCurrentCorrelationMetadata():\n | TraceCorrelationMetadata\n | undefined {\n try {\n return extractCorrelationMetadata(storage.getStore()?.metadata);\n } catch {\n return undefined;\n }\n}\n\n/** Active `runName` when inside `runWithContext`, else `undefined`. */\nexport function getCurrentRunName(): string | undefined {\n try {\n return storage.getStore()?.runName;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Active step id in this async scope (parent for nested `step()` calls).\n * `undefined` at run root or outside any run.\n */\nexport function getCurrentStepId(): string | undefined {\n try {\n return storage.getStore()?.currentStepId;\n } catch {\n return undefined;\n }\n}\n\n/** Alias of {@link getCurrentStepId} for readability in step instrumentation. */\nexport function getParentStepId(): string | undefined {\n return getCurrentStepId();\n}\n\n/**\n * Nesting depth: `0` at run root, increments by one per nested `runWithStepContext`.\n * Returns `0` outside any run.\n */\nexport function getCurrentDepth(): number {\n try {\n const d = storage.getStore()?.currentDepth;\n return typeof d === \"number\" && Number.isFinite(d) ? d : 0;\n } catch {\n return 0;\n }\n}\n\nexport function hasActiveContext(): boolean {\n try {\n return storage.getStore() !== undefined;\n } catch {\n return false;\n }\n}\n\nexport function getTraceDirFromContext(): string | undefined {\n try {\n return storage.getStore()?.traceDir;\n } catch {\n return undefined;\n }\n}\n\nexport function isSilentContext(): boolean {\n try {\n const s = storage.getStore();\n return s ? s.silent : false;\n } catch {\n return false;\n }\n}\n\n/** Resolved trace safety settings for the active run (redaction + size bounds). */\nexport function getTraceSafetyFromContext(): TraceSafetyOptions | undefined {\n try {\n return storage.getStore()?.traceSafety;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Runs `fn` with a fresh AgentInspect run context (depth 0, no active step).\n * Propagates sync/async results and rejections; does not swallow user errors.\n */\nexport function runWithContext<T>(\n context: ExecutionContext,\n fn: () => Promise<T> | T,\n traceSafety: TraceSafetyOptions = resolveTraceSafetyOptions(),\n): Promise<T> {\n const runtime: RuntimeExecutionContext = {\n runId: context.runId,\n runName: context.runName,\n traceDir: context.traceDir,\n silent: context.silent,\n metadata: context.metadata,\n traceSafety,\n currentDepth: 0,\n };\n\n return new Promise((resolve, reject) => {\n storage.run(runtime, () => {\n try {\n Promise.resolve(fn()).then(resolve, reject);\n } catch (e) {\n reject(e);\n }\n });\n });\n}\n\n/**\n * Runs `fn` with `stepId` as the active step (incremented depth).\n * If no run is active, runs `fn` without altering async context.\n */\nexport function runWithStepContext<T>(\n stepId: string,\n fn: () => Promise<T> | T,\n): Promise<T> {\n let parent: RuntimeExecutionContext | undefined;\n try {\n parent = storage.getStore();\n } catch {\n parent = undefined;\n }\n\n if (!parent) {\n return invoke(fn);\n }\n\n const derived: RuntimeExecutionContext = {\n runId: parent.runId,\n runName: parent.runName,\n traceDir: parent.traceDir,\n silent: parent.silent,\n metadata: parent.metadata,\n traceSafety: parent.traceSafety,\n currentStepId: stepId,\n currentDepth: parent.currentDepth + 1,\n };\n\n return new Promise((resolve, reject) => {\n storage.run(derived, () => {\n try {\n Promise.resolve(fn()).then(resolve, reject);\n } catch (e) {\n reject(e);\n }\n });\n });\n}\n","import chalk from \"chalk\";\n\nimport { isSilentContext } from \"./context.js\";\nimport type { ErrorInfo, RunStatus, StepStatus } from \"./types.js\";\nimport { formatDuration, truncateName } from \"./utils.js\";\n\n/** Two spaces per nesting level in terminal output. */\nexport const TERMINAL_INDENT = \" \";\n\n/** Max display length for names in terminal output. */\nexport const MAX_TERMINAL_NAME_LENGTH = 80;\n\n/** Max nesting depth used for indentation (prevents huge indents). */\nexport const MAX_TERMINAL_DEPTH = 10;\n\nfunction normalizeDepth(depth: number): number {\n if (!Number.isFinite(depth) || depth < 0) {\n return 0;\n }\n return Math.min(Math.floor(depth), MAX_TERMINAL_DEPTH);\n}\n\nfunction safePrint(line = \"\"): void {\n try {\n console.log(line);\n } catch {\n /* never break callers */\n }\n}\n\n/** Indentation string for a nesting depth (capped, never negative). */\nexport function getIndent(depth: number): string {\n return TERMINAL_INDENT.repeat(normalizeDepth(depth));\n}\n\n/** Truncates a display name for terminal use; invalid input becomes `\"unnamed\"`. */\nexport function formatTerminalName(name: string): string {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n return \"unnamed\";\n }\n return truncateName(name, MAX_TERMINAL_NAME_LENGTH);\n}\n\nfunction getStatusIcon(status: StepStatus | RunStatus): string {\n if (status === \"success\") return chalk.green(\"✔\");\n if (status === \"error\") return chalk.red(\"✖\");\n return chalk.yellow(\"⏳\");\n}\n\n/** Renders a single step line (colored); does not consult silent mode. */\nexport function renderStepLine(\n name: string,\n durationMs: number | undefined,\n status: StepStatus,\n depth?: number,\n): string {\n try {\n const nm = formatTerminalName(name);\n const ind = getIndent(depth ?? 0);\n if (status === \"running\" && durationMs === undefined) {\n return `${ind}${chalk.yellow(\"⏳\")} ${nm}`;\n }\n const hasDur =\n durationMs !== undefined && Number.isFinite(durationMs as number);\n const dur = hasDur ? formatDuration(durationMs as number) : undefined;\n if (status === \"running\") {\n return dur !== undefined\n ? `${ind}${chalk.yellow(\"⏳\")} ${nm} (${dur})`\n : `${ind}${chalk.yellow(\"⏳\")} ${nm}`;\n }\n if (!hasDur || dur === undefined) {\n return `${ind}${chalk.yellow(\"⏳\")} ${nm}`;\n }\n if (status === \"success\") {\n return `${ind}${getStatusIcon(\"success\")} ${nm} (${dur})`;\n }\n return `${ind}${getStatusIcon(\"error\")} ${nm} (${dur})`;\n } catch {\n return \"\";\n }\n}\n\n/** Renders an error summary line (no stack in MVP). */\nexport function renderErrorLine(error: ErrorInfo, depth?: number): string {\n try {\n const msg =\n typeof error.message === \"string\" ? error.message : \"\";\n const ind = getIndent((depth ?? 0) + 1);\n return `${ind}Error: ${msg}`;\n } catch {\n return \"\";\n }\n}\n\n/** Plain-text run summary lines (no chalk) for stable testing and CLI reuse. */\nexport function renderRunSummary(\n durationMs: number,\n status: RunStatus,\n traceFilePath?: string,\n): string[] {\n try {\n const dur = Number.isFinite(durationMs)\n ? formatDuration(durationMs)\n : formatDuration(0);\n const head =\n status === \"error\" ? `Failed in ${dur}` : `Completed in ${dur}`;\n const lines = [head];\n if (traceFilePath !== undefined && traceFilePath.trim() !== \"\") {\n lines.push(`Trace: ${traceFilePath}`);\n }\n return lines;\n } catch {\n return [];\n }\n}\n\n/** Prints run header with icon and dim run id. */\nexport function printRunStart(runId: string, name: string): void {\n if (isSilentContext()) return;\n try {\n safePrint(\"\");\n const header = `${chalk.cyan.bold(\"🔍 AgentInspect:\")} ${formatTerminalName(name)} ${chalk.dim(`(${runId})`)}`;\n safePrint(header);\n } catch {\n /* noop */\n }\n}\n\n/** Prints a running step line. */\nexport function printStepStart(name: string, depth = 0): void {\n if (isSilentContext()) return;\n try {\n safePrint(renderStepLine(name, undefined, \"running\", depth));\n } catch {\n /* noop */\n }\n}\n\n/** Prints a completed step line with duration and status icon. */\nexport function printStepComplete(\n name: string,\n durationMs: number,\n status: StepStatus,\n depth = 0,\n): void {\n if (isSilentContext()) return;\n try {\n safePrint(renderStepLine(name, durationMs, status, depth));\n } catch {\n /* noop */\n }\n}\n\n/** Prints a structured error line (message only, no stack). */\nexport function printError(error: ErrorInfo, depth = 0): void {\n if (isSilentContext()) return;\n try {\n safePrint(renderErrorLine(error, depth));\n } catch {\n /* noop */\n }\n}\n\n/** Prints run completion summary and optional trace path. */\nexport function printRunComplete(\n _name: string,\n _runId: string,\n durationMs: number,\n status: RunStatus,\n traceFilePath?: string,\n): void {\n if (isSilentContext()) return;\n try {\n const lines = renderRunSummary(durationMs, status, traceFilePath);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n if (i === 0) {\n const color =\n status === \"error\"\n ? chalk.red\n : status === \"running\"\n ? chalk.yellow\n : chalk.green;\n safePrint(color(line));\n } else {\n safePrint(chalk.dim(line));\n }\n }\n } catch {\n /* noop */\n }\n}\n\n/** Prints which step failed. */\nexport function printFailedAt(stepName: string): void {\n if (isSilentContext()) return;\n try {\n safePrint(`Failed at: ${formatTerminalName(stepName)}`);\n } catch {\n /* noop */\n }\n}\n","import {\n getCurrentContext,\n getCurrentDepth,\n getParentStepId,\n getTraceSafetyFromContext,\n runWithStepContext,\n} from \"./context.js\";\nimport type { StepOptions, StepType, TraceEvent } from \"./types.js\";\nimport { writeTraceEvent } from \"./storage.js\";\nimport { printFailedAt, printError, printStepComplete, printStepStart } from \"./terminal.js\";\nimport { prepareTraceEventForDisk } from \"./trace-event-safety.js\";\nimport { createStepId, formatError, truncateName, warn } from \"./utils.js\";\n\nfunction normalizeStepName(name: unknown): string {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n return \"unnamed-step\";\n }\n return truncateName(name.trim(), 100);\n}\n\nasync function safeInstrumentation(\n label: string,\n op: () => void | Promise<void>,\n): Promise<void> {\n try {\n await Promise.resolve(op());\n } catch (e) {\n warn(`step: ${label}`, e);\n }\n}\n\nasync function stepImpl<T>(\n name: string,\n fn: () => Promise<T> | T,\n options?: StepOptions,\n): Promise<T> {\n if (typeof fn !== \"function\") {\n throw new TypeError(\"step requires `fn` to be a function\");\n }\n\n const stepName = normalizeStepName(name);\n const context = getCurrentContext();\n\n if (!context) {\n warn(\"step() called outside inspectRun(); executing without instrumentation\");\n return Promise.resolve(fn());\n }\n\n const stepId = createStepId();\n const renderDepth = getCurrentDepth();\n const parentId = getParentStepId();\n const stepType: StepType = options?.type ?? \"logic\";\n const metadata = options?.metadata;\n const traceSafety = getTraceSafetyFromContext();\n const startTime = Date.now();\n\n await safeInstrumentation(\"writeTraceEvent(step_started)\", async () => {\n const started: TraceEvent = {\n schemaVersion: \"0.1\",\n event: \"step_started\",\n timestamp: startTime,\n runId: context.runId,\n stepId,\n ...(typeof parentId === \"string\" && parentId.trim() !== \"\"\n ? { parentId }\n : {}),\n name: stepName,\n type: stepType,\n startTime,\n ...(metadata !== undefined ? { metadata } : {}),\n };\n const safe =\n traceSafety !== undefined\n ? prepareTraceEventForDisk(started, traceSafety)\n : started;\n await writeTraceEvent(safe, context.traceDir);\n });\n\n await safeInstrumentation(\"printStepStart\", () => {\n printStepStart(stepName, renderDepth);\n });\n\n let result: T;\n try {\n result = await runWithStepContext(stepId, async () => {\n return await Promise.resolve(fn());\n });\n } catch (userError) {\n const endTime = Date.now();\n const durationMs = endTime - startTime;\n const formatted = formatError(userError);\n\n await safeInstrumentation(\"writeTraceEvent(step_completed error)\", async () => {\n const completed: TraceEvent = {\n schemaVersion: \"0.1\",\n event: \"step_completed\",\n timestamp: endTime,\n runId: context.runId,\n stepId,\n status: \"error\",\n endTime,\n durationMs,\n error: formatted,\n };\n const safe =\n traceSafety !== undefined\n ? prepareTraceEventForDisk(completed, traceSafety)\n : completed;\n await writeTraceEvent(safe, context.traceDir);\n });\n\n await safeInstrumentation(\"printStepComplete(error)\", () => {\n printStepComplete(stepName, durationMs, \"error\", renderDepth);\n });\n await safeInstrumentation(\"printError\", () => {\n printError(formatted, renderDepth);\n });\n await safeInstrumentation(\"printFailedAt\", () => {\n printFailedAt(stepName);\n });\n\n throw userError;\n }\n\n const endTime = Date.now();\n const durationMs = endTime - startTime;\n\n await safeInstrumentation(\"writeTraceEvent(step_completed success)\", async () => {\n const completed: TraceEvent = {\n schemaVersion: \"0.1\",\n event: \"step_completed\",\n timestamp: endTime,\n runId: context.runId,\n stepId,\n status: \"success\",\n endTime,\n durationMs,\n };\n const safe =\n traceSafety !== undefined\n ? prepareTraceEventForDisk(completed, traceSafety)\n : completed;\n await writeTraceEvent(safe, context.traceDir);\n });\n\n await safeInstrumentation(\"printStepComplete(success)\", () => {\n printStepComplete(stepName, durationMs, \"success\", renderDepth);\n });\n\n return result;\n}\n\n/**\n * Stable v1.0 API for instrumenting a named step inside an AgentInspect run.\n *\n * Callable step tracer plus {@link step.llm} and {@link step.tool} shortcuts.\n */\nexport type StepFunction = {\n <T>(name: string, fn: () => Promise<T> | T, options?: StepOptions): Promise<T>;\n llm: <T>(model: string, fn: () => Promise<T> | T) => Promise<T>;\n tool: <T>(toolName: string, fn: () => Promise<T> | T) => Promise<T>;\n};\n\nasync function stepLlm<T>(model: string, fn: () => Promise<T> | T): Promise<T> {\n const modelName =\n typeof model === \"string\" && model.trim() !== \"\"\n ? model.trim()\n : \"unknown-model\";\n return stepImpl<T>(`llm:${modelName}`, fn, {\n type: \"llm\",\n metadata: { model: modelName },\n });\n}\n\nasync function stepTool<T>(\n toolName: string,\n fn: () => Promise<T> | T,\n): Promise<T> {\n const normalized =\n typeof toolName === \"string\" && toolName.trim() !== \"\"\n ? toolName.trim()\n : \"unknown-tool\";\n return stepImpl<T>(`tool:${normalized}`, fn, {\n type: \"tool\",\n metadata: { toolName: normalized },\n });\n}\n\n/**\n * Traces a named unit of work inside `inspectRun` (`step_started` / `step_completed`, optional terminal).\n * Outside a run, executes `fn` with a warn only. Preserves return values and rethrows user errors unchanged.\n *\n * - `step.llm(model, fn)` — `type: \"llm\"`, `metadata.model` (no SDK calls or token counting).\n * - `step.tool(toolName, fn)` — `type: \"tool\"`, `metadata.toolName` (no framework interception).\n */\nexport const step = Object.assign(stepImpl, {\n llm: stepLlm,\n tool: stepTool,\n}) as StepFunction;\n","import { step } from \"agent-inspect\";\n\nimport { hashServerUrl, summarizeMcpValue } from \"./summarize.js\";\nimport type {\n McpClientLike,\n McpClientTracerOptions,\n McpTraceMetadata,\n} from \"./types.js\";\n\nlet toolCallCounter = 0;\n\nfunction nextToolCallId(prefix?: string): string {\n toolCallCounter += 1;\n const base = prefix?.trim() || \"mcp\";\n return `${base}-${toolCallCounter}`;\n}\n\nfunction baseMetadata(\n options: McpClientTracerOptions,\n overrides: Partial<McpTraceMetadata> = {},\n): Record<string, unknown> {\n const metadata: McpTraceMetadata = {\n source: { type: \"mcp-client\" },\n ...(options.serverName ? { mcpServerName: options.serverName } : {}),\n ...(options.serverUrl\n ? { mcpServerUrlHash: hashServerUrl(options.serverUrl) }\n : {}),\n ...(options.sessionId ? { sessionId: options.sessionId } : {}),\n ...overrides,\n };\n return { ...(options.metadata ?? {}), ...metadata };\n}\n\n/**\n * Wraps an MCP client so tools/list and tools/call emit local tool steps.\n * Telemetry only — does not proxy network behavior beyond the wrapped client.\n */\nexport function wrapMcpClient<T extends McpClientLike>(\n client: T,\n options: McpClientTracerOptions = {},\n): T {\n const maxSummaryLength = options.maxSummaryLength ?? 240;\n const wrapped = { ...client } as T;\n\n if (typeof client.listTools === \"function\") {\n const listTools = client.listTools.bind(client);\n wrapped.listTools = async (params?: unknown) =>\n step(\n \"mcp:tools/list\",\n async () => {\n const result = await listTools(params);\n return result;\n },\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: \"tools/list\",\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n }),\n },\n );\n }\n\n const callTool = client.callTool.bind(client);\n wrapped.callTool = async (params) =>\n step(\n `mcp:${params.name}`,\n async () => callTool(params),\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: params.name,\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n argumentSummary: summarizeMcpValue(\n params.arguments ?? {},\n maxSummaryLength,\n ),\n }),\n },\n );\n\n return wrapped;\n}\n\n/** @internal resets tool call ids for deterministic tests */\nexport function resetMcpToolCallIdsForTests(): void {\n toolCallCounter = 0;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-inspect/mcp",
3
- "version": "4.3.0",
3
+ "version": "4.4.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Local MCP client tool-call tracing for AgentInspect",
@@ -34,7 +34,7 @@
34
34
  "dist"
35
35
  ],
36
36
  "dependencies": {
37
- "agent-inspect": "4.3.0"
37
+ "agent-inspect": "4.4.0"
38
38
  },
39
39
  "publishConfig": {
40
40
  "access": "public"