@mastra/code-sdk 1.5.2-alpha.1 → 1.5.2-alpha.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"process-memory-diagnostics.js","names":[],"sources":["../src/process-memory-diagnostics.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { appendFile, chmod, mkdir, rename, rm, writeFile } from 'node:fs/promises';\nimport { Session } from 'node:inspector/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { PerformanceObserver, type PerformanceEntry } from 'node:perf_hooks';\nimport { arch, platform } from 'node:process';\nimport { getHeapSpaceStatistics, getHeapStatistics } from 'node:v8';\n\nexport const PROCESS_MEMORY_DIAGNOSTICS_DEFAULTS = {\n sampleIntervalMs: 10_000,\n captureIntervalMs: 300_000,\n allocationIntervalBytes: 524_288,\n} as const;\n\nexport const PROCESS_MEMORY_DIAGNOSTICS_MINIMUMS = {\n sampleIntervalMs: 1_000,\n captureIntervalMs: 10_000,\n allocationIntervalBytes: 32_768,\n} as const;\n\nconst MAX_TIMER_DELAY_MS = 2_147_483_647;\nconst MAX_PENDING_GC_EVENTS = 1_000;\n\nexport interface ProcessMemoryDiagnosticsConfig {\n parentDirectory: string;\n sampleIntervalMs: number;\n captureIntervalMs: number;\n allocationIntervalBytes: number;\n}\n\nexport interface ProcessMemoryDiagnosticsEnvironment {\n MASTRACODE_PROFILE?: string;\n MASTRACODE_PROFILE_DIR?: string;\n MASTRACODE_PROFILE_SAMPLE_INTERVAL_MS?: string;\n MASTRACODE_PROFILE_CAPTURE_INTERVAL_MS?: string;\n MASTRACODE_PROFILE_ALLOCATION_INTERVAL_BYTES?: string;\n}\n\nexport interface ProcessMemoryDiagnosticsMemorySample {\n timestamp: string;\n sequence: number;\n elapsedMs: number;\n memory: ReturnType<typeof process.memoryUsage>;\n resourceUsage: ReturnType<typeof process.resourceUsage>;\n heap: ReturnType<typeof getHeapStatistics>;\n heapSpaces: ReturnType<typeof getHeapSpaceStatistics>;\n}\n\nexport interface ProcessMemoryDiagnosticsStatus {\n state: 'inactive' | 'starting' | 'active' | 'stopping' | 'error';\n outputDirectory: string | null;\n config: ProcessMemoryDiagnosticsConfig;\n sampleCount: number;\n captureCount: number;\n gcEventCount: number;\n latestSample: ProcessMemoryDiagnosticsMemorySample | null;\n latestCapturePath: string | null;\n error: string | null;\n}\n\nexport interface ProcessMemoryDiagnosticsCapture {\n path: string;\n sequence: number;\n timestamp: string;\n reason: 'manual' | 'periodic' | 'stop';\n}\n\ninterface InspectorSessionAdapter {\n connect(): void;\n disconnect(): void;\n post(method: string, params?: Record<string, unknown>): Promise<Record<string, unknown>>;\n}\n\ninterface PerformanceObserverAdapter {\n observe(options: Parameters<PerformanceObserver['observe']>[0]): void;\n disconnect(): void;\n}\n\ninterface ProcessMemoryDiagnosticsDependencies {\n createInspectorSession?: () => InspectorSessionAdapter;\n createPerformanceObserver?: (callback: (entries: PerformanceEntry[]) => void) => PerformanceObserverAdapter;\n now?: () => Date;\n randomId?: () => string;\n}\n\nexport interface ProcessMemoryDiagnosticsSetup {\n diagnostics: ProcessMemoryDiagnostics;\n enabled: boolean;\n error: string | null;\n}\n\nexport class ProcessMemoryDiagnosticsConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ProcessMemoryDiagnosticsConfigError';\n }\n}\n\nfunction isEnabled(value: string | undefined): boolean {\n return ['1', 'true', 'yes', 'on'].includes(value?.trim().toLowerCase() ?? '');\n}\n\nfunction parseBoundedInteger(\n env: ProcessMemoryDiagnosticsEnvironment,\n name: keyof ProcessMemoryDiagnosticsEnvironment,\n fallback: number,\n minimum: number,\n maximum?: number,\n): number {\n const raw = env[name];\n if (raw === undefined || raw.trim() === '') return fallback;\n const value = Number(raw);\n if (!Number.isSafeInteger(value) || value < minimum || (maximum !== undefined && value > maximum)) {\n const range = maximum === undefined ? `greater than or equal to ${minimum}` : `between ${minimum} and ${maximum}`;\n throw new ProcessMemoryDiagnosticsConfigError(\n `${name} must be an integer ${range}; received ${JSON.stringify(raw)}.`,\n );\n }\n return value;\n}\n\nfunction getDefaultProfileParentDirectory(): string {\n if (process.env.MASTRA_APP_DATA_DIR) return join(process.env.MASTRA_APP_DATA_DIR, 'profiles');\n\n const baseDirectory =\n platform === 'darwin'\n ? join(homedir(), 'Library', 'Application Support')\n : platform === 'win32'\n ? process.env.APPDATA || join(homedir(), 'AppData', 'Roaming')\n : process.env.XDG_DATA_HOME || join(homedir(), '.local', 'share');\n return join(baseDirectory, 'mastracode', 'profiles');\n}\n\nexport function parseProcessMemoryDiagnosticsEnvironment(env: ProcessMemoryDiagnosticsEnvironment = process.env): {\n enabled: boolean;\n config: ProcessMemoryDiagnosticsConfig;\n} {\n return {\n enabled: isEnabled(env.MASTRACODE_PROFILE),\n config: {\n parentDirectory: env.MASTRACODE_PROFILE_DIR?.trim() || getDefaultProfileParentDirectory(),\n sampleIntervalMs: parseBoundedInteger(\n env,\n 'MASTRACODE_PROFILE_SAMPLE_INTERVAL_MS',\n PROCESS_MEMORY_DIAGNOSTICS_DEFAULTS.sampleIntervalMs,\n PROCESS_MEMORY_DIAGNOSTICS_MINIMUMS.sampleIntervalMs,\n MAX_TIMER_DELAY_MS,\n ),\n captureIntervalMs: parseBoundedInteger(\n env,\n 'MASTRACODE_PROFILE_CAPTURE_INTERVAL_MS',\n PROCESS_MEMORY_DIAGNOSTICS_DEFAULTS.captureIntervalMs,\n PROCESS_MEMORY_DIAGNOSTICS_MINIMUMS.captureIntervalMs,\n MAX_TIMER_DELAY_MS,\n ),\n allocationIntervalBytes: parseBoundedInteger(\n env,\n 'MASTRACODE_PROFILE_ALLOCATION_INTERVAL_BYTES',\n PROCESS_MEMORY_DIAGNOSTICS_DEFAULTS.allocationIntervalBytes,\n PROCESS_MEMORY_DIAGNOSTICS_MINIMUMS.allocationIntervalBytes,\n ),\n },\n };\n}\n\nexport function createProcessMemoryDiagnosticsFromEnvironment(\n env: ProcessMemoryDiagnosticsEnvironment = process.env,\n dependencies: ProcessMemoryDiagnosticsDependencies = {},\n): ProcessMemoryDiagnosticsSetup {\n try {\n const { enabled, config } = parseProcessMemoryDiagnosticsEnvironment(env);\n return { diagnostics: new ProcessMemoryDiagnostics(config, dependencies), enabled, error: null };\n } catch (error) {\n const config: ProcessMemoryDiagnosticsConfig = {\n parentDirectory: env.MASTRACODE_PROFILE_DIR?.trim() || getDefaultProfileParentDirectory(),\n ...PROCESS_MEMORY_DIAGNOSTICS_DEFAULTS,\n };\n const message = error instanceof Error ? error.message : String(error);\n return {\n diagnostics: new ProcessMemoryDiagnostics(config, dependencies, message),\n enabled: isEnabled(env.MASTRACODE_PROFILE),\n error: message,\n };\n }\n}\n\nexport async function startConfiguredProcessMemoryDiagnostics(\n setup: ProcessMemoryDiagnosticsSetup,\n warn: (message: string) => void,\n): Promise<ProcessMemoryDiagnostics> {\n if (!setup.enabled) return setup.diagnostics;\n if (setup.error) {\n warn(`Process memory diagnostics were not started: ${setup.error}`);\n return setup.diagnostics;\n }\n\n const status = await setup.diagnostics.start();\n if (status.state !== 'active') {\n warn(`Process memory diagnostics were not started: ${status.error ?? 'unknown inspector error'}`);\n }\n return setup.diagnostics;\n}\n\nexport async function stopProcessMemoryDiagnosticsWithTimeout(\n diagnostics: ProcessMemoryDiagnostics,\n warn: (message: string) => void,\n timeoutMs = 5_000,\n): Promise<void> {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n const timedOut = await Promise.race([\n diagnostics.stop().then(\n () => false,\n error => {\n warn(`Process memory diagnostics did not stop cleanly: ${errorMessage(error)}`);\n return false;\n },\n ),\n new Promise<true>(resolve => {\n timeout = setTimeout(() => resolve(true), timeoutMs);\n timeout.unref();\n }),\n ]);\n if (timeout) clearTimeout(timeout);\n if (timedOut)\n warn(`Process memory diagnostics did not stop within ${timeoutMs}ms; final artifacts may be incomplete.`);\n}\n\nfunction defaultInspectorSession(): InspectorSessionAdapter {\n const session = new Session();\n return {\n connect: () => session.connect(),\n disconnect: () => session.disconnect(),\n post: async (method, params) =>\n (await session.post(\n method as Parameters<Session['post']>[0],\n params as Parameters<Session['post']>[1],\n )) as unknown as Record<string, unknown>,\n };\n}\n\nfunction defaultPerformanceObserver(callback: (entries: PerformanceEntry[]) => void) {\n const observer = new PerformanceObserver(list => callback(list.getEntries()));\n return observer;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction safeTimestamp(date: Date): string {\n return date.toISOString().replaceAll(':', '-');\n}\n\nfunction unrefTimer(timer: ReturnType<typeof setInterval>): void {\n timer.unref?.();\n}\n\nexport class ProcessMemoryDiagnostics {\n readonly config: ProcessMemoryDiagnosticsConfig;\n\n private state: ProcessMemoryDiagnosticsStatus['state'] = 'inactive';\n private outputDirectory: string | null = null;\n private inspector: InspectorSessionAdapter | null = null;\n private observer: PerformanceObserverAdapter | null = null;\n private sampleTimer: ReturnType<typeof setInterval> | null = null;\n private captureTimer: ReturnType<typeof setInterval> | null = null;\n private startedAt: Date | null = null;\n private sampleCount = 0;\n private captureCount = 0;\n private gcEventCount = 0;\n private latestSample: ProcessMemoryDiagnosticsMemorySample | null = null;\n private latestCapturePath: string | null = null;\n private latestError: string | null;\n private samplingActive = false;\n private stopRequested = false;\n private startingPromise: Promise<ProcessMemoryDiagnosticsStatus> | null = null;\n private stoppingPromise: Promise<ProcessMemoryDiagnosticsStatus> | null = null;\n private restartAfterStopPromise: Promise<ProcessMemoryDiagnosticsStatus> | null = null;\n private restartRequested = false;\n private pendingGcEvents: Array<Record<string, unknown>> = [];\n private gcEventBufferOverflowed = false;\n private artifactWriteFailed = false;\n private captureQueue: Promise<unknown> = Promise.resolve();\n private writeQueue: Promise<unknown> = Promise.resolve();\n\n private readonly configError: string | null;\n private readonly createInspectorSession: () => InspectorSessionAdapter;\n private readonly createPerformanceObserver: NonNullable<\n ProcessMemoryDiagnosticsDependencies['createPerformanceObserver']\n >;\n private readonly now: () => Date;\n private readonly randomId: () => string;\n\n constructor(\n config: ProcessMemoryDiagnosticsConfig,\n dependencies: ProcessMemoryDiagnosticsDependencies = {},\n initialError: string | null = null,\n ) {\n this.config = { ...config };\n this.configError = initialError;\n this.latestError = initialError;\n this.createInspectorSession = dependencies.createInspectorSession ?? defaultInspectorSession;\n this.createPerformanceObserver = dependencies.createPerformanceObserver ?? defaultPerformanceObserver;\n this.now = dependencies.now ?? (() => new Date());\n this.randomId = dependencies.randomId ?? randomUUID;\n }\n\n getStatus(): ProcessMemoryDiagnosticsStatus {\n return {\n state: this.state,\n outputDirectory: this.outputDirectory,\n config: { ...this.config },\n sampleCount: this.sampleCount,\n captureCount: this.captureCount,\n gcEventCount: this.gcEventCount,\n latestSample: this.latestSample,\n latestCapturePath: this.latestCapturePath,\n error: this.latestError,\n };\n }\n\n start(): Promise<ProcessMemoryDiagnosticsStatus> {\n if (this.state === 'active') return Promise.resolve(this.getStatus());\n if (this.state === 'starting' && this.startingPromise) return this.startingPromise;\n if (this.state === 'stopping' && this.stoppingPromise) {\n this.restartRequested = true;\n this.restartAfterStopPromise ??= this.stoppingPromise.then(() => {\n this.restartAfterStopPromise = null;\n if (!this.restartRequested) return this.getStatus();\n this.restartRequested = false;\n return this.start();\n });\n return this.restartAfterStopPromise;\n }\n if (this.configError) {\n this.latestError = this.configError;\n this.state = 'error';\n return Promise.resolve(this.getStatus());\n }\n\n this.state = 'starting';\n this.stoppingPromise = null;\n this.restartRequested = false;\n this.stopRequested = false;\n this.outputDirectory = null;\n this.sampleCount = 0;\n this.captureCount = 0;\n this.gcEventCount = 0;\n this.pendingGcEvents = [];\n this.gcEventBufferOverflowed = false;\n this.artifactWriteFailed = false;\n this.latestSample = null;\n this.latestCapturePath = null;\n this.latestError = null;\n this.startedAt = this.now();\n\n const startingPromise = this.startRun();\n this.startingPromise = startingPromise;\n void startingPromise.finally(() => {\n if (this.startingPromise === startingPromise) this.startingPromise = null;\n });\n return startingPromise;\n }\n\n private async startRun(): Promise<ProcessMemoryDiagnosticsStatus> {\n try {\n await this.createArtifacts();\n if (await this.abortStartIfRequested()) return this.getStatus();\n\n this.observeGc();\n this.inspector = this.createInspectorSession();\n this.inspector.connect();\n await this.startSampling();\n if (await this.abortStartIfRequested()) return this.getStatus();\n\n await this.takeSample();\n if (await this.abortStartIfRequested()) return this.getStatus();\n\n this.sampleTimer = setInterval(() => {\n void this.takeSample().catch(error => this.recordError('Process sample failed', error));\n }, this.config.sampleIntervalMs);\n unrefTimer(this.sampleTimer);\n\n this.captureTimer = setInterval(() => {\n void this.capture('periodic').catch(error => this.recordError('Periodic allocation capture failed', error));\n }, this.config.captureIntervalMs);\n unrefTimer(this.captureTimer);\n\n this.state = 'active';\n return this.getStatus();\n } catch (error) {\n this.latestError = `Unable to start process memory diagnostics: ${errorMessage(error)}`;\n await this.cleanupAfterStartFailure();\n this.state = 'error';\n return this.getStatus();\n }\n }\n\n private async abortStartIfRequested(): Promise<boolean> {\n if (!this.stopRequested) return false;\n await this.cleanupAfterStartFailure();\n this.state = 'inactive';\n return true;\n }\n\n capture(reason: 'manual' | 'periodic' = 'manual'): Promise<ProcessMemoryDiagnosticsCapture> {\n if (this.state !== 'active') {\n return Promise.reject(new Error(this.latestError ?? 'Process memory diagnostics are not active.'));\n }\n return this.enqueueCapture(() => this.captureEpoch(reason, false));\n }\n\n async stop(): Promise<ProcessMemoryDiagnosticsStatus> {\n if (this.stoppingPromise) {\n this.restartRequested = false;\n return this.stoppingPromise;\n }\n if (this.state === 'inactive') return this.getStatus();\n if (this.state === 'error' && !this.inspector && !this.outputDirectory) return this.getStatus();\n\n const startingPromise = this.state === 'starting' ? this.startingPromise : null;\n this.stopRequested = true;\n this.state = 'stopping';\n this.clearTimersAndObserver();\n\n if (startingPromise) {\n this.stoppingPromise = startingPromise.then(() => this.getStatus());\n return this.stoppingPromise;\n }\n\n this.stoppingPromise = (async () => {\n let stopError: string | null = null;\n try {\n if (this.outputDirectory) await this.takeSample();\n await this.enqueueCapture(async () => {\n if (this.inspector && this.samplingActive) await this.captureEpoch('stop', true);\n });\n await this.writeQueue;\n if (this.gcEventBufferOverflowed) {\n throw new Error(`GC event buffer exceeded ${MAX_PENDING_GC_EVENTS} records before the next process sample.`);\n }\n if (this.artifactWriteFailed) throw new Error('One or more process memory diagnostic artifact writes failed.');\n this.latestError = null;\n } catch (error) {\n stopError = `Unable to stop process memory diagnostics cleanly: ${errorMessage(error)}`;\n this.latestError = stopError;\n } finally {\n this.disconnectInspector();\n this.state = stopError ? 'error' : 'inactive';\n }\n return this.getStatus();\n })();\n\n return this.stoppingPromise;\n }\n\n private async createArtifacts(): Promise<void> {\n await mkdir(this.config.parentDirectory, { recursive: true, mode: 0o700 });\n await chmod(this.config.parentDirectory, 0o700);\n const runName = `run-${safeTimestamp(this.startedAt!)}-${process.pid}-${this.randomId()\n .replaceAll(/[^a-zA-Z0-9-]/g, '')\n .slice(0, 12)}`;\n this.outputDirectory = join(this.config.parentDirectory, runName);\n await mkdir(this.outputDirectory, { mode: 0o700 });\n await chmod(this.outputDirectory, 0o700);\n\n const metadata = {\n schemaVersion: 1,\n runId: runName,\n startedAt: this.startedAt!.toISOString(),\n pid: process.pid,\n nodeVersion: process.version,\n platform,\n arch,\n config: this.config,\n };\n await writeFile(join(this.outputDirectory, 'metadata.json'), `${JSON.stringify(metadata, null, 2)}\\n`, {\n flag: 'wx',\n mode: 0o600,\n });\n await writeFile(join(this.outputDirectory, 'process-samples.jsonl'), '', { flag: 'wx', mode: 0o600 });\n await writeFile(join(this.outputDirectory, 'gc-events.jsonl'), '', { flag: 'wx', mode: 0o600 });\n }\n\n private observeGc(): void {\n const observer = this.createPerformanceObserver(entries => {\n const before = this.latestSample?.memory ?? null;\n const after = process.memoryUsage();\n const timestamp = this.now().toISOString();\n for (const entry of entries) {\n const gcEntry = entry as PerformanceEntry & {\n kind?: number;\n flags?: number;\n detail?: { kind?: number; flags?: number };\n };\n this.gcEventCount += 1;\n if (this.pendingGcEvents.length >= MAX_PENDING_GC_EVENTS) {\n this.gcEventBufferOverflowed = true;\n this.latestError = `GC event buffer exceeded ${MAX_PENDING_GC_EVENTS} records before the next process sample.`;\n continue;\n }\n this.pendingGcEvents.push({\n timestamp,\n sequence: this.gcEventCount,\n name: entry.name,\n startTime: entry.startTime,\n duration: entry.duration,\n kind: gcEntry.detail?.kind ?? gcEntry.kind ?? null,\n flags: gcEntry.detail?.flags ?? gcEntry.flags ?? null,\n before,\n after,\n latestSampleSequence: this.latestSample?.sequence ?? null,\n });\n }\n });\n observer.observe({ entryTypes: ['gc'] });\n this.observer = observer;\n }\n\n private async startSampling(): Promise<void> {\n if (!this.inspector) throw new Error('Inspector session is unavailable.');\n await this.inspector.post('HeapProfiler.startSampling', {\n samplingInterval: this.config.allocationIntervalBytes,\n includeObjectsCollectedByMajorGC: true,\n includeObjectsCollectedByMinorGC: true,\n });\n this.samplingActive = true;\n }\n\n private async takeSample(): Promise<ProcessMemoryDiagnosticsMemorySample> {\n if (!this.outputDirectory || !this.startedAt) throw new Error('Diagnostics output directory is unavailable.');\n const sample: ProcessMemoryDiagnosticsMemorySample = {\n timestamp: this.now().toISOString(),\n sequence: this.sampleCount + 1,\n elapsedMs: Math.max(0, this.now().getTime() - this.startedAt.getTime()),\n memory: process.memoryUsage(),\n resourceUsage: process.resourceUsage(),\n heap: getHeapStatistics(),\n heapSpaces: getHeapSpaceStatistics(),\n };\n this.sampleCount = sample.sequence;\n this.latestSample = sample;\n await this.enqueueWrite('process-samples.jsonl', sample);\n const gcEvents = this.pendingGcEvents.splice(0);\n if (gcEvents.length > 0) await this.enqueueWriteBatch('gc-events.jsonl', gcEvents);\n return sample;\n }\n\n private enqueueWrite(fileName: string, value: unknown): Promise<void> {\n return this.enqueueWriteBatch(fileName, [value]);\n }\n\n private enqueueWriteBatch(fileName: string, values: unknown[]): Promise<void> {\n const operation = this.writeQueue.then(async () => {\n if (!this.outputDirectory || values.length === 0) return;\n const lines = values.map(value => JSON.stringify(value)).join('\\n');\n try {\n await appendFile(join(this.outputDirectory, fileName), `${lines}\\n`, { mode: 0o600 });\n } catch (error) {\n this.artifactWriteFailed = true;\n throw error;\n }\n });\n this.writeQueue = operation.catch(() => undefined);\n return operation;\n }\n\n private enqueueCapture<T>(operation: () => Promise<T>): Promise<T> {\n const result = this.captureQueue.then(operation);\n this.captureQueue = result.catch(() => undefined);\n return result;\n }\n\n private async captureEpoch(\n reason: ProcessMemoryDiagnosticsCapture['reason'],\n final: boolean,\n ): Promise<ProcessMemoryDiagnosticsCapture> {\n if (!this.inspector || !this.samplingActive || !this.outputDirectory) {\n throw new Error(this.latestError ?? 'Allocation sampling is not active.');\n }\n\n let response: Record<string, unknown>;\n try {\n response = await this.inspector.post('HeapProfiler.stopSampling');\n this.samplingActive = false;\n } catch (error) {\n this.latestError = `Allocation capture failed: ${errorMessage(error)}`;\n if (!final && !this.stopRequested) await this.restartSamplingAfterFailure();\n throw new Error(this.latestError, { cause: error });\n }\n\n const profile = response.profile;\n if (!profile || typeof profile !== 'object') {\n this.latestError = 'Allocation capture failed: inspector returned no profile.';\n if (!final && !this.stopRequested) await this.restartSamplingAfterFailure();\n throw new Error(this.latestError);\n }\n\n const sequence = this.captureCount + 1;\n const timestamp = this.now().toISOString();\n const filename = `allocation-${String(sequence).padStart(6, '0')}-${safeTimestamp(new Date(timestamp))}.heapprofile`;\n const finalPath = join(this.outputDirectory, filename);\n const temporaryPath = join(this.outputDirectory, `.${filename}.${this.randomId()}.tmp`);\n\n try {\n await writeFile(temporaryPath, `${JSON.stringify(profile)}\\n`, { flag: 'wx', mode: 0o600 });\n await chmod(temporaryPath, 0o600);\n await rename(temporaryPath, finalPath);\n await chmod(finalPath, 0o600);\n this.captureCount = sequence;\n this.latestCapturePath = finalPath;\n this.latestError = null;\n } catch (error) {\n this.artifactWriteFailed = true;\n this.latestError = `Unable to persist allocation capture: ${errorMessage(error)}`;\n throw new Error(this.latestError, { cause: error });\n } finally {\n if (!final && !this.stopRequested && this.state === 'active') {\n try {\n await this.startSampling();\n } catch (error) {\n this.latestError = `Unable to restart allocation sampling: ${errorMessage(error)}`;\n this.state = 'error';\n }\n }\n }\n\n if (!final && !this.stopRequested && !this.samplingActive) {\n throw new Error(this.latestError ?? 'Allocation sampling did not restart.');\n }\n\n return { path: finalPath, sequence, timestamp, reason };\n }\n\n private async restartSamplingAfterFailure(): Promise<void> {\n try {\n await this.startSampling();\n } catch (error) {\n this.latestError = `Unable to restart allocation sampling: ${errorMessage(error)}`;\n this.state = 'error';\n }\n }\n\n private recordError(prefix: string, error: unknown): void {\n this.latestError = `${prefix}: ${errorMessage(error)}`;\n }\n\n private clearTimersAndObserver(): void {\n if (this.sampleTimer) clearInterval(this.sampleTimer);\n if (this.captureTimer) clearInterval(this.captureTimer);\n this.sampleTimer = null;\n this.captureTimer = null;\n this.observer?.disconnect();\n this.observer = null;\n }\n\n private disconnectInspector(): void {\n this.samplingActive = false;\n if (!this.inspector) return;\n try {\n this.inspector.disconnect();\n } catch {\n // Best-effort cleanup after an inspector failure.\n }\n this.inspector = null;\n }\n\n private async cleanupAfterStartFailure(): Promise<void> {\n this.clearTimersAndObserver();\n this.disconnectInspector();\n await this.writeQueue;\n try {\n if (this.outputDirectory) await rm(this.outputDirectory, { recursive: true, force: true });\n } catch (error) {\n this.latestError = `${this.latestError} Failed to remove partial artifacts: ${errorMessage(error)}`;\n } finally {\n this.outputDirectory = null;\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"process-memory-diagnostics.js","names":["platform"],"sources":["../src/process-memory-diagnostics.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { appendFile, chmod, mkdir, rename, rm, writeFile } from 'node:fs/promises';\nimport { Session } from 'node:inspector/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { PerformanceObserver, type PerformanceEntry } from 'node:perf_hooks';\nimport { arch, platform } from 'node:process';\nimport { getHeapSpaceStatistics, getHeapStatistics } from 'node:v8';\n\nexport const PROCESS_MEMORY_DIAGNOSTICS_DEFAULTS = {\n sampleIntervalMs: 10_000,\n captureIntervalMs: 300_000,\n allocationIntervalBytes: 524_288,\n} as const;\n\nexport const PROCESS_MEMORY_DIAGNOSTICS_MINIMUMS = {\n sampleIntervalMs: 1_000,\n captureIntervalMs: 10_000,\n allocationIntervalBytes: 32_768,\n} as const;\n\nconst MAX_TIMER_DELAY_MS = 2_147_483_647;\nconst MAX_PENDING_GC_EVENTS = 1_000;\n\nexport interface ProcessMemoryDiagnosticsConfig {\n parentDirectory: string;\n sampleIntervalMs: number;\n captureIntervalMs: number;\n allocationIntervalBytes: number;\n}\n\nexport interface ProcessMemoryDiagnosticsEnvironment {\n MASTRACODE_PROFILE?: string;\n MASTRACODE_PROFILE_DIR?: string;\n MASTRACODE_PROFILE_SAMPLE_INTERVAL_MS?: string;\n MASTRACODE_PROFILE_CAPTURE_INTERVAL_MS?: string;\n MASTRACODE_PROFILE_ALLOCATION_INTERVAL_BYTES?: string;\n}\n\nexport interface ProcessMemoryDiagnosticsMemorySample {\n timestamp: string;\n sequence: number;\n elapsedMs: number;\n memory: ReturnType<typeof process.memoryUsage>;\n resourceUsage: ReturnType<typeof process.resourceUsage>;\n heap: ReturnType<typeof getHeapStatistics>;\n heapSpaces: ReturnType<typeof getHeapSpaceStatistics>;\n}\n\nexport interface ProcessMemoryDiagnosticsStatus {\n state: 'inactive' | 'starting' | 'active' | 'stopping' | 'error';\n outputDirectory: string | null;\n config: ProcessMemoryDiagnosticsConfig;\n sampleCount: number;\n captureCount: number;\n gcEventCount: number;\n latestSample: ProcessMemoryDiagnosticsMemorySample | null;\n latestCapturePath: string | null;\n error: string | null;\n}\n\nexport interface ProcessMemoryDiagnosticsCapture {\n path: string;\n sequence: number;\n timestamp: string;\n reason: 'manual' | 'periodic' | 'stop';\n}\n\ninterface InspectorSessionAdapter {\n connect(): void;\n disconnect(): void;\n post(method: string, params?: Record<string, unknown>): Promise<Record<string, unknown>>;\n}\n\ninterface PerformanceObserverAdapter {\n observe(options: Parameters<PerformanceObserver['observe']>[0]): void;\n disconnect(): void;\n}\n\ninterface ProcessMemoryDiagnosticsDependencies {\n createInspectorSession?: () => InspectorSessionAdapter;\n createPerformanceObserver?: (callback: (entries: PerformanceEntry[]) => void) => PerformanceObserverAdapter;\n now?: () => Date;\n randomId?: () => string;\n}\n\nexport interface ProcessMemoryDiagnosticsSetup {\n diagnostics: ProcessMemoryDiagnostics;\n enabled: boolean;\n error: string | null;\n}\n\nexport class ProcessMemoryDiagnosticsConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ProcessMemoryDiagnosticsConfigError';\n }\n}\n\nfunction isEnabled(value: string | undefined): boolean {\n return ['1', 'true', 'yes', 'on'].includes(value?.trim().toLowerCase() ?? '');\n}\n\nfunction parseBoundedInteger(\n env: ProcessMemoryDiagnosticsEnvironment,\n name: keyof ProcessMemoryDiagnosticsEnvironment,\n fallback: number,\n minimum: number,\n maximum?: number,\n): number {\n const raw = env[name];\n if (raw === undefined || raw.trim() === '') return fallback;\n const value = Number(raw);\n if (!Number.isSafeInteger(value) || value < minimum || (maximum !== undefined && value > maximum)) {\n const range = maximum === undefined ? `greater than or equal to ${minimum}` : `between ${minimum} and ${maximum}`;\n throw new ProcessMemoryDiagnosticsConfigError(\n `${name} must be an integer ${range}; received ${JSON.stringify(raw)}.`,\n );\n }\n return value;\n}\n\nfunction getDefaultProfileParentDirectory(): string {\n if (process.env.MASTRA_APP_DATA_DIR) return join(process.env.MASTRA_APP_DATA_DIR, 'profiles');\n\n const baseDirectory =\n platform === 'darwin'\n ? join(homedir(), 'Library', 'Application Support')\n : platform === 'win32'\n ? process.env.APPDATA || join(homedir(), 'AppData', 'Roaming')\n : process.env.XDG_DATA_HOME || join(homedir(), '.local', 'share');\n return join(baseDirectory, 'mastracode', 'profiles');\n}\n\nexport function parseProcessMemoryDiagnosticsEnvironment(env: ProcessMemoryDiagnosticsEnvironment = process.env): {\n enabled: boolean;\n config: ProcessMemoryDiagnosticsConfig;\n} {\n return {\n enabled: isEnabled(env.MASTRACODE_PROFILE),\n config: {\n parentDirectory: env.MASTRACODE_PROFILE_DIR?.trim() || getDefaultProfileParentDirectory(),\n sampleIntervalMs: parseBoundedInteger(\n env,\n 'MASTRACODE_PROFILE_SAMPLE_INTERVAL_MS',\n PROCESS_MEMORY_DIAGNOSTICS_DEFAULTS.sampleIntervalMs,\n PROCESS_MEMORY_DIAGNOSTICS_MINIMUMS.sampleIntervalMs,\n MAX_TIMER_DELAY_MS,\n ),\n captureIntervalMs: parseBoundedInteger(\n env,\n 'MASTRACODE_PROFILE_CAPTURE_INTERVAL_MS',\n PROCESS_MEMORY_DIAGNOSTICS_DEFAULTS.captureIntervalMs,\n PROCESS_MEMORY_DIAGNOSTICS_MINIMUMS.captureIntervalMs,\n MAX_TIMER_DELAY_MS,\n ),\n allocationIntervalBytes: parseBoundedInteger(\n env,\n 'MASTRACODE_PROFILE_ALLOCATION_INTERVAL_BYTES',\n PROCESS_MEMORY_DIAGNOSTICS_DEFAULTS.allocationIntervalBytes,\n PROCESS_MEMORY_DIAGNOSTICS_MINIMUMS.allocationIntervalBytes,\n ),\n },\n };\n}\n\nexport function createProcessMemoryDiagnosticsFromEnvironment(\n env: ProcessMemoryDiagnosticsEnvironment = process.env,\n dependencies: ProcessMemoryDiagnosticsDependencies = {},\n): ProcessMemoryDiagnosticsSetup {\n try {\n const { enabled, config } = parseProcessMemoryDiagnosticsEnvironment(env);\n return { diagnostics: new ProcessMemoryDiagnostics(config, dependencies), enabled, error: null };\n } catch (error) {\n const config: ProcessMemoryDiagnosticsConfig = {\n parentDirectory: env.MASTRACODE_PROFILE_DIR?.trim() || getDefaultProfileParentDirectory(),\n ...PROCESS_MEMORY_DIAGNOSTICS_DEFAULTS,\n };\n const message = error instanceof Error ? error.message : String(error);\n return {\n diagnostics: new ProcessMemoryDiagnostics(config, dependencies, message),\n enabled: isEnabled(env.MASTRACODE_PROFILE),\n error: message,\n };\n }\n}\n\nexport async function startConfiguredProcessMemoryDiagnostics(\n setup: ProcessMemoryDiagnosticsSetup,\n warn: (message: string) => void,\n): Promise<ProcessMemoryDiagnostics> {\n if (!setup.enabled) return setup.diagnostics;\n if (setup.error) {\n warn(`Process memory diagnostics were not started: ${setup.error}`);\n return setup.diagnostics;\n }\n\n const status = await setup.diagnostics.start();\n if (status.state !== 'active') {\n warn(`Process memory diagnostics were not started: ${status.error ?? 'unknown inspector error'}`);\n }\n return setup.diagnostics;\n}\n\nexport async function stopProcessMemoryDiagnosticsWithTimeout(\n diagnostics: ProcessMemoryDiagnostics,\n warn: (message: string) => void,\n timeoutMs = 5_000,\n): Promise<void> {\n let timeout: ReturnType<typeof setTimeout> | undefined;\n const timedOut = await Promise.race([\n diagnostics.stop().then(\n () => false,\n error => {\n warn(`Process memory diagnostics did not stop cleanly: ${errorMessage(error)}`);\n return false;\n },\n ),\n new Promise<true>(resolve => {\n timeout = setTimeout(() => resolve(true), timeoutMs);\n timeout.unref();\n }),\n ]);\n if (timeout) clearTimeout(timeout);\n if (timedOut)\n warn(`Process memory diagnostics did not stop within ${timeoutMs}ms; final artifacts may be incomplete.`);\n}\n\nfunction defaultInspectorSession(): InspectorSessionAdapter {\n const session = new Session();\n return {\n connect: () => session.connect(),\n disconnect: () => session.disconnect(),\n post: async (method, params) =>\n (await session.post(\n method as Parameters<Session['post']>[0],\n params as Parameters<Session['post']>[1],\n )) as unknown as Record<string, unknown>,\n };\n}\n\nfunction defaultPerformanceObserver(callback: (entries: PerformanceEntry[]) => void) {\n const observer = new PerformanceObserver(list => callback(list.getEntries()));\n return observer;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction safeTimestamp(date: Date): string {\n return date.toISOString().replaceAll(':', '-');\n}\n\nfunction unrefTimer(timer: ReturnType<typeof setInterval>): void {\n timer.unref?.();\n}\n\nexport class ProcessMemoryDiagnostics {\n readonly config: ProcessMemoryDiagnosticsConfig;\n\n private state: ProcessMemoryDiagnosticsStatus['state'] = 'inactive';\n private outputDirectory: string | null = null;\n private inspector: InspectorSessionAdapter | null = null;\n private observer: PerformanceObserverAdapter | null = null;\n private sampleTimer: ReturnType<typeof setInterval> | null = null;\n private captureTimer: ReturnType<typeof setInterval> | null = null;\n private startedAt: Date | null = null;\n private sampleCount = 0;\n private captureCount = 0;\n private gcEventCount = 0;\n private latestSample: ProcessMemoryDiagnosticsMemorySample | null = null;\n private latestCapturePath: string | null = null;\n private latestError: string | null;\n private samplingActive = false;\n private stopRequested = false;\n private startingPromise: Promise<ProcessMemoryDiagnosticsStatus> | null = null;\n private stoppingPromise: Promise<ProcessMemoryDiagnosticsStatus> | null = null;\n private restartAfterStopPromise: Promise<ProcessMemoryDiagnosticsStatus> | null = null;\n private restartRequested = false;\n private pendingGcEvents: Array<Record<string, unknown>> = [];\n private gcEventBufferOverflowed = false;\n private artifactWriteFailed = false;\n private captureQueue: Promise<unknown> = Promise.resolve();\n private writeQueue: Promise<unknown> = Promise.resolve();\n\n private readonly configError: string | null;\n private readonly createInspectorSession: () => InspectorSessionAdapter;\n private readonly createPerformanceObserver: NonNullable<\n ProcessMemoryDiagnosticsDependencies['createPerformanceObserver']\n >;\n private readonly now: () => Date;\n private readonly randomId: () => string;\n\n constructor(\n config: ProcessMemoryDiagnosticsConfig,\n dependencies: ProcessMemoryDiagnosticsDependencies = {},\n initialError: string | null = null,\n ) {\n this.config = { ...config };\n this.configError = initialError;\n this.latestError = initialError;\n this.createInspectorSession = dependencies.createInspectorSession ?? defaultInspectorSession;\n this.createPerformanceObserver = dependencies.createPerformanceObserver ?? defaultPerformanceObserver;\n this.now = dependencies.now ?? (() => new Date());\n this.randomId = dependencies.randomId ?? randomUUID;\n }\n\n getStatus(): ProcessMemoryDiagnosticsStatus {\n return {\n state: this.state,\n outputDirectory: this.outputDirectory,\n config: { ...this.config },\n sampleCount: this.sampleCount,\n captureCount: this.captureCount,\n gcEventCount: this.gcEventCount,\n latestSample: this.latestSample,\n latestCapturePath: this.latestCapturePath,\n error: this.latestError,\n };\n }\n\n start(): Promise<ProcessMemoryDiagnosticsStatus> {\n if (this.state === 'active') return Promise.resolve(this.getStatus());\n if (this.state === 'starting' && this.startingPromise) return this.startingPromise;\n if (this.state === 'stopping' && this.stoppingPromise) {\n this.restartRequested = true;\n this.restartAfterStopPromise ??= this.stoppingPromise.then(() => {\n this.restartAfterStopPromise = null;\n if (!this.restartRequested) return this.getStatus();\n this.restartRequested = false;\n return this.start();\n });\n return this.restartAfterStopPromise;\n }\n if (this.configError) {\n this.latestError = this.configError;\n this.state = 'error';\n return Promise.resolve(this.getStatus());\n }\n\n this.state = 'starting';\n this.stoppingPromise = null;\n this.restartRequested = false;\n this.stopRequested = false;\n this.outputDirectory = null;\n this.sampleCount = 0;\n this.captureCount = 0;\n this.gcEventCount = 0;\n this.pendingGcEvents = [];\n this.gcEventBufferOverflowed = false;\n this.artifactWriteFailed = false;\n this.latestSample = null;\n this.latestCapturePath = null;\n this.latestError = null;\n this.startedAt = this.now();\n\n const startingPromise = this.startRun();\n this.startingPromise = startingPromise;\n void startingPromise.finally(() => {\n if (this.startingPromise === startingPromise) this.startingPromise = null;\n });\n return startingPromise;\n }\n\n private async startRun(): Promise<ProcessMemoryDiagnosticsStatus> {\n try {\n await this.createArtifacts();\n if (await this.abortStartIfRequested()) return this.getStatus();\n\n this.observeGc();\n this.inspector = this.createInspectorSession();\n this.inspector.connect();\n await this.startSampling();\n if (await this.abortStartIfRequested()) return this.getStatus();\n\n await this.takeSample();\n if (await this.abortStartIfRequested()) return this.getStatus();\n\n this.sampleTimer = setInterval(() => {\n void this.takeSample().catch(error => this.recordError('Process sample failed', error));\n }, this.config.sampleIntervalMs);\n unrefTimer(this.sampleTimer);\n\n this.captureTimer = setInterval(() => {\n void this.capture('periodic').catch(error => this.recordError('Periodic allocation capture failed', error));\n }, this.config.captureIntervalMs);\n unrefTimer(this.captureTimer);\n\n this.state = 'active';\n return this.getStatus();\n } catch (error) {\n this.latestError = `Unable to start process memory diagnostics: ${errorMessage(error)}`;\n await this.cleanupAfterStartFailure();\n this.state = 'error';\n return this.getStatus();\n }\n }\n\n private async abortStartIfRequested(): Promise<boolean> {\n if (!this.stopRequested) return false;\n await this.cleanupAfterStartFailure();\n this.state = 'inactive';\n return true;\n }\n\n capture(reason: 'manual' | 'periodic' = 'manual'): Promise<ProcessMemoryDiagnosticsCapture> {\n if (this.state !== 'active') {\n return Promise.reject(new Error(this.latestError ?? 'Process memory diagnostics are not active.'));\n }\n return this.enqueueCapture(() => this.captureEpoch(reason, false));\n }\n\n async stop(): Promise<ProcessMemoryDiagnosticsStatus> {\n if (this.stoppingPromise) {\n this.restartRequested = false;\n return this.stoppingPromise;\n }\n if (this.state === 'inactive') return this.getStatus();\n if (this.state === 'error' && !this.inspector && !this.outputDirectory) return this.getStatus();\n\n const startingPromise = this.state === 'starting' ? this.startingPromise : null;\n this.stopRequested = true;\n this.state = 'stopping';\n this.clearTimersAndObserver();\n\n if (startingPromise) {\n this.stoppingPromise = startingPromise.then(() => this.getStatus());\n return this.stoppingPromise;\n }\n\n this.stoppingPromise = (async () => {\n let stopError: string | null = null;\n try {\n if (this.outputDirectory) await this.takeSample();\n await this.enqueueCapture(async () => {\n if (this.inspector && this.samplingActive) await this.captureEpoch('stop', true);\n });\n await this.writeQueue;\n if (this.gcEventBufferOverflowed) {\n throw new Error(`GC event buffer exceeded ${MAX_PENDING_GC_EVENTS} records before the next process sample.`);\n }\n if (this.artifactWriteFailed) throw new Error('One or more process memory diagnostic artifact writes failed.');\n this.latestError = null;\n } catch (error) {\n stopError = `Unable to stop process memory diagnostics cleanly: ${errorMessage(error)}`;\n this.latestError = stopError;\n } finally {\n this.disconnectInspector();\n this.state = stopError ? 'error' : 'inactive';\n }\n return this.getStatus();\n })();\n\n return this.stoppingPromise;\n }\n\n private async createArtifacts(): Promise<void> {\n await mkdir(this.config.parentDirectory, { recursive: true, mode: 0o700 });\n await chmod(this.config.parentDirectory, 0o700);\n const runName = `run-${safeTimestamp(this.startedAt!)}-${process.pid}-${this.randomId()\n .replaceAll(/[^a-zA-Z0-9-]/g, '')\n .slice(0, 12)}`;\n this.outputDirectory = join(this.config.parentDirectory, runName);\n await mkdir(this.outputDirectory, { mode: 0o700 });\n await chmod(this.outputDirectory, 0o700);\n\n const metadata = {\n schemaVersion: 1,\n runId: runName,\n startedAt: this.startedAt!.toISOString(),\n pid: process.pid,\n nodeVersion: process.version,\n platform,\n arch,\n config: this.config,\n };\n await writeFile(join(this.outputDirectory, 'metadata.json'), `${JSON.stringify(metadata, null, 2)}\\n`, {\n flag: 'wx',\n mode: 0o600,\n });\n await writeFile(join(this.outputDirectory, 'process-samples.jsonl'), '', { flag: 'wx', mode: 0o600 });\n await writeFile(join(this.outputDirectory, 'gc-events.jsonl'), '', { flag: 'wx', mode: 0o600 });\n }\n\n private observeGc(): void {\n const observer = this.createPerformanceObserver(entries => {\n const before = this.latestSample?.memory ?? null;\n const after = process.memoryUsage();\n const timestamp = this.now().toISOString();\n for (const entry of entries) {\n const gcEntry = entry as PerformanceEntry & {\n kind?: number;\n flags?: number;\n detail?: { kind?: number; flags?: number };\n };\n this.gcEventCount += 1;\n if (this.pendingGcEvents.length >= MAX_PENDING_GC_EVENTS) {\n this.gcEventBufferOverflowed = true;\n this.latestError = `GC event buffer exceeded ${MAX_PENDING_GC_EVENTS} records before the next process sample.`;\n continue;\n }\n this.pendingGcEvents.push({\n timestamp,\n sequence: this.gcEventCount,\n name: entry.name,\n startTime: entry.startTime,\n duration: entry.duration,\n kind: gcEntry.detail?.kind ?? gcEntry.kind ?? null,\n flags: gcEntry.detail?.flags ?? gcEntry.flags ?? null,\n before,\n after,\n latestSampleSequence: this.latestSample?.sequence ?? null,\n });\n }\n });\n observer.observe({ entryTypes: ['gc'] });\n this.observer = observer;\n }\n\n private async startSampling(): Promise<void> {\n if (!this.inspector) throw new Error('Inspector session is unavailable.');\n await this.inspector.post('HeapProfiler.startSampling', {\n samplingInterval: this.config.allocationIntervalBytes,\n includeObjectsCollectedByMajorGC: true,\n includeObjectsCollectedByMinorGC: true,\n });\n this.samplingActive = true;\n }\n\n private async takeSample(): Promise<ProcessMemoryDiagnosticsMemorySample> {\n if (!this.outputDirectory || !this.startedAt) throw new Error('Diagnostics output directory is unavailable.');\n const sample: ProcessMemoryDiagnosticsMemorySample = {\n timestamp: this.now().toISOString(),\n sequence: this.sampleCount + 1,\n elapsedMs: Math.max(0, this.now().getTime() - this.startedAt.getTime()),\n memory: process.memoryUsage(),\n resourceUsage: process.resourceUsage(),\n heap: getHeapStatistics(),\n heapSpaces: getHeapSpaceStatistics(),\n };\n this.sampleCount = sample.sequence;\n this.latestSample = sample;\n await this.enqueueWrite('process-samples.jsonl', sample);\n const gcEvents = this.pendingGcEvents.splice(0);\n if (gcEvents.length > 0) await this.enqueueWriteBatch('gc-events.jsonl', gcEvents);\n return sample;\n }\n\n private enqueueWrite(fileName: string, value: unknown): Promise<void> {\n return this.enqueueWriteBatch(fileName, [value]);\n }\n\n private enqueueWriteBatch(fileName: string, values: unknown[]): Promise<void> {\n const operation = this.writeQueue.then(async () => {\n if (!this.outputDirectory || values.length === 0) return;\n const lines = values.map(value => JSON.stringify(value)).join('\\n');\n try {\n await appendFile(join(this.outputDirectory, fileName), `${lines}\\n`, { mode: 0o600 });\n } catch (error) {\n this.artifactWriteFailed = true;\n throw error;\n }\n });\n this.writeQueue = operation.catch(() => undefined);\n return operation;\n }\n\n private enqueueCapture<T>(operation: () => Promise<T>): Promise<T> {\n const result = this.captureQueue.then(operation);\n this.captureQueue = result.catch(() => undefined);\n return result;\n }\n\n private async captureEpoch(\n reason: ProcessMemoryDiagnosticsCapture['reason'],\n final: boolean,\n ): Promise<ProcessMemoryDiagnosticsCapture> {\n if (!this.inspector || !this.samplingActive || !this.outputDirectory) {\n throw new Error(this.latestError ?? 'Allocation sampling is not active.');\n }\n\n let response: Record<string, unknown>;\n try {\n response = await this.inspector.post('HeapProfiler.stopSampling');\n this.samplingActive = false;\n } catch (error) {\n this.latestError = `Allocation capture failed: ${errorMessage(error)}`;\n if (!final && !this.stopRequested) await this.restartSamplingAfterFailure();\n throw new Error(this.latestError, { cause: error });\n }\n\n const profile = response.profile;\n if (!profile || typeof profile !== 'object') {\n this.latestError = 'Allocation capture failed: inspector returned no profile.';\n if (!final && !this.stopRequested) await this.restartSamplingAfterFailure();\n throw new Error(this.latestError);\n }\n\n const sequence = this.captureCount + 1;\n const timestamp = this.now().toISOString();\n const filename = `allocation-${String(sequence).padStart(6, '0')}-${safeTimestamp(new Date(timestamp))}.heapprofile`;\n const finalPath = join(this.outputDirectory, filename);\n const temporaryPath = join(this.outputDirectory, `.${filename}.${this.randomId()}.tmp`);\n\n try {\n await writeFile(temporaryPath, `${JSON.stringify(profile)}\\n`, { flag: 'wx', mode: 0o600 });\n await chmod(temporaryPath, 0o600);\n await rename(temporaryPath, finalPath);\n await chmod(finalPath, 0o600);\n this.captureCount = sequence;\n this.latestCapturePath = finalPath;\n this.latestError = null;\n } catch (error) {\n this.artifactWriteFailed = true;\n this.latestError = `Unable to persist allocation capture: ${errorMessage(error)}`;\n throw new Error(this.latestError, { cause: error });\n } finally {\n if (!final && !this.stopRequested && this.state === 'active') {\n try {\n await this.startSampling();\n } catch (error) {\n this.latestError = `Unable to restart allocation sampling: ${errorMessage(error)}`;\n this.state = 'error';\n }\n }\n }\n\n if (!final && !this.stopRequested && !this.samplingActive) {\n throw new Error(this.latestError ?? 'Allocation sampling did not restart.');\n }\n\n return { path: finalPath, sequence, timestamp, reason };\n }\n\n private async restartSamplingAfterFailure(): Promise<void> {\n try {\n await this.startSampling();\n } catch (error) {\n this.latestError = `Unable to restart allocation sampling: ${errorMessage(error)}`;\n this.state = 'error';\n }\n }\n\n private recordError(prefix: string, error: unknown): void {\n this.latestError = `${prefix}: ${errorMessage(error)}`;\n }\n\n private clearTimersAndObserver(): void {\n if (this.sampleTimer) clearInterval(this.sampleTimer);\n if (this.captureTimer) clearInterval(this.captureTimer);\n this.sampleTimer = null;\n this.captureTimer = null;\n this.observer?.disconnect();\n this.observer = null;\n }\n\n private disconnectInspector(): void {\n this.samplingActive = false;\n if (!this.inspector) return;\n try {\n this.inspector.disconnect();\n } catch {\n // Best-effort cleanup after an inspector failure.\n }\n this.inspector = null;\n }\n\n private async cleanupAfterStartFailure(): Promise<void> {\n this.clearTimersAndObserver();\n this.disconnectInspector();\n await this.writeQueue;\n try {\n if (this.outputDirectory) await rm(this.outputDirectory, { recursive: true, force: true });\n } catch (error) {\n this.latestError = `${this.latestError} Failed to remove partial artifacts: ${errorMessage(error)}`;\n } finally {\n this.outputDirectory = null;\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { MastraModelConfig } from '@mastra/core/llm';
2
+ import { AuthStorage } from '../auth/storage.js';
3
+ import type { CredentialStore } from '../auth/types.js';
4
+ export declare const KIMI_CODING_MODELS: readonly ["k3", "k3-256k", "kimi-for-coding", "kimi-for-coding-highspeed"];
5
+ export declare function setAuthStorage(storage: AuthStorage | undefined): void;
6
+ export declare function buildKimiCodingOAuthFetch(options?: {
7
+ credentialStore?: CredentialStore;
8
+ }): typeof fetch;
9
+ export declare function buildKimiCodingApiKeyFetch(apiKey: string): typeof fetch;
10
+ export declare function kimiCodingProvider(modelId: string, options: {
11
+ apiKey: string;
12
+ headers?: Record<string, string>;
13
+ credentialStore?: CredentialStore;
14
+ }): MastraModelConfig;
15
+ //# sourceMappingURL=kimi-coding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kimi-coding.d.ts","sourceRoot":"","sources":["../../src/providers/kimi-coding.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAOxD,eAAO,MAAM,kBAAkB,4EAA6E,CAAC;AAI7G,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,CAErE;AAOD,wBAAgB,yBAAyB,CAAC,OAAO,GAAE;IAAE,eAAe,CAAC,EAAE,eAAe,CAAA;CAAO,GAAG,OAAO,KAAK,CAuB3G;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,KAAK,CASvE;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,eAAe,CAAC,EAAE,eAAe,CAAA;CAAE,GAC/F,iBAAiB,CAWnB"}
@@ -0,0 +1,69 @@
1
+ import { getKimiCodingDeviceHeaders, isKimiCodingDeviceId } from "../auth/providers/kimi-coding.js";
2
+ import { AuthStorage } from "../auth/storage.js";
3
+ import { ProviderAuthRequiredError } from "../auth/provider-auth-error.js";
4
+ import { createAnthropic } from "@ai-sdk/anthropic";
5
+ //#region src/providers/kimi-coding.ts
6
+ const PROVIDER_ID = "kimi-for-coding";
7
+ const BASE_URL = "https://api.kimi.com/coding/v1";
8
+ const KIMI_CODING_MODELS = [
9
+ "k3",
10
+ "k3-256k",
11
+ "kimi-for-coding",
12
+ "kimi-for-coding-highspeed"
13
+ ];
14
+ let authStorageInstance = null;
15
+ function setAuthStorage(storage) {
16
+ authStorageInstance = storage ?? null;
17
+ }
18
+ function getAuthStorage() {
19
+ if (!authStorageInstance) authStorageInstance = new AuthStorage();
20
+ return authStorageInstance;
21
+ }
22
+ function buildKimiCodingOAuthFetch(options = {}) {
23
+ return (async (input, init) => {
24
+ const store = options.credentialStore ?? getAuthStorage();
25
+ store.reload();
26
+ const credential = store.get(PROVIDER_ID);
27
+ if (!credential || credential.type !== "oauth") throw new ProviderAuthRequiredError("Not logged in to Kimi For Coding.");
28
+ if (!isKimiCodingDeviceId(credential.deviceId)) throw new ProviderAuthRequiredError("Kimi For Coding credentials are invalid. Please reconnect the account.");
29
+ const deviceHeaders = getKimiCodingDeviceHeaders(credential.deviceId);
30
+ const token = await store.getApiKey(PROVIDER_ID);
31
+ if (!token) throw new ProviderAuthRequiredError("Failed to refresh the Kimi For Coding token.");
32
+ const headers = new Headers(input instanceof Request ? input.headers : void 0);
33
+ if (init?.headers) new Headers(init.headers).forEach((value, key) => headers.set(key, value));
34
+ for (const [key, value] of Object.entries(deviceHeaders)) headers.set(key, value);
35
+ headers.delete("authorization");
36
+ headers.delete("x-api-key");
37
+ headers.set("Authorization", `Bearer ${token}`);
38
+ return fetch(input, {
39
+ ...init,
40
+ headers
41
+ });
42
+ });
43
+ }
44
+ function buildKimiCodingApiKeyFetch(apiKey) {
45
+ return (async (input, init) => {
46
+ const headers = new Headers(input instanceof Request ? input.headers : void 0);
47
+ if (init?.headers) new Headers(init.headers).forEach((value, key) => headers.set(key, value));
48
+ headers.delete("authorization");
49
+ headers.delete("x-api-key");
50
+ headers.set("Authorization", `Bearer ${apiKey}`);
51
+ return fetch(input, {
52
+ ...init,
53
+ headers
54
+ });
55
+ });
56
+ }
57
+ function kimiCodingProvider(modelId, options) {
58
+ const usesOAuth = options.credentialStore?.get(PROVIDER_ID)?.type === "oauth";
59
+ return createAnthropic({
60
+ apiKey: "auth-placeholder",
61
+ baseURL: BASE_URL,
62
+ headers: options.headers,
63
+ fetch: usesOAuth ? buildKimiCodingOAuthFetch({ credentialStore: options.credentialStore }) : buildKimiCodingApiKeyFetch(options.apiKey)
64
+ })(modelId);
65
+ }
66
+ //#endregion
67
+ export { KIMI_CODING_MODELS, buildKimiCodingApiKeyFetch, buildKimiCodingOAuthFetch, kimiCodingProvider, setAuthStorage };
68
+
69
+ //# sourceMappingURL=kimi-coding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kimi-coding.js","names":[],"sources":["../../src/providers/kimi-coding.ts"],"sourcesContent":["import { createAnthropic } from '@ai-sdk/anthropic';\nimport type { MastraModelConfig } from '@mastra/core/llm';\nimport { ProviderAuthRequiredError } from '../auth/provider-auth-error.js';\nimport { getKimiCodingDeviceHeaders, isKimiCodingDeviceId } from '../auth/providers/kimi-coding.js';\nimport { AuthStorage } from '../auth/storage.js';\nimport type { CredentialStore } from '../auth/types.js';\n\nconst PROVIDER_ID = 'kimi-for-coding';\n// Pi's provider root is https://api.kimi.com/coding. The AI SDK expects the\n// versioned Anthropic base URL and appends /messages itself.\nconst BASE_URL = 'https://api.kimi.com/coding/v1';\n\nexport const KIMI_CODING_MODELS = ['k3', 'k3-256k', 'kimi-for-coding', 'kimi-for-coding-highspeed'] as const;\n\nlet authStorageInstance: AuthStorage | null = null;\n\nexport function setAuthStorage(storage: AuthStorage | undefined): void {\n authStorageInstance = storage ?? null;\n}\n\nfunction getAuthStorage(): AuthStorage {\n if (!authStorageInstance) authStorageInstance = new AuthStorage();\n return authStorageInstance;\n}\n\nexport function buildKimiCodingOAuthFetch(options: { credentialStore?: CredentialStore } = {}): typeof fetch {\n return (async (input: string | URL | Request, init?: Parameters<typeof fetch>[1]) => {\n const store = options.credentialStore ?? getAuthStorage();\n store.reload();\n const credential = store.get(PROVIDER_ID);\n if (!credential || credential.type !== 'oauth') {\n throw new ProviderAuthRequiredError('Not logged in to Kimi For Coding.');\n }\n if (!isKimiCodingDeviceId(credential.deviceId)) {\n throw new ProviderAuthRequiredError('Kimi For Coding credentials are invalid. Please reconnect the account.');\n }\n const deviceHeaders = getKimiCodingDeviceHeaders(credential.deviceId);\n const token = await store.getApiKey(PROVIDER_ID);\n if (!token) throw new ProviderAuthRequiredError('Failed to refresh the Kimi For Coding token.');\n\n const headers = new Headers(input instanceof Request ? input.headers : undefined);\n if (init?.headers) new Headers(init.headers).forEach((value, key) => headers.set(key, value));\n for (const [key, value] of Object.entries(deviceHeaders)) headers.set(key, value);\n headers.delete('authorization');\n headers.delete('x-api-key');\n headers.set('Authorization', `Bearer ${token}`);\n return fetch(input, { ...init, headers });\n }) as typeof fetch;\n}\n\nexport function buildKimiCodingApiKeyFetch(apiKey: string): typeof fetch {\n return (async (input: string | URL | Request, init?: Parameters<typeof fetch>[1]) => {\n const headers = new Headers(input instanceof Request ? input.headers : undefined);\n if (init?.headers) new Headers(init.headers).forEach((value, key) => headers.set(key, value));\n headers.delete('authorization');\n headers.delete('x-api-key');\n headers.set('Authorization', `Bearer ${apiKey}`);\n return fetch(input, { ...init, headers });\n }) as typeof fetch;\n}\n\nexport function kimiCodingProvider(\n modelId: string,\n options: { apiKey: string; headers?: Record<string, string>; credentialStore?: CredentialStore },\n): MastraModelConfig {\n const usesOAuth = options.credentialStore?.get(PROVIDER_ID)?.type === 'oauth';\n const provider = createAnthropic({\n apiKey: 'auth-placeholder',\n baseURL: BASE_URL,\n headers: options.headers,\n fetch: usesOAuth\n ? (buildKimiCodingOAuthFetch({ credentialStore: options.credentialStore }) as any)\n : (buildKimiCodingApiKeyFetch(options.apiKey) as any),\n });\n return provider(modelId) as unknown as MastraModelConfig;\n}\n"],"mappings":";;;;;AAOA,MAAM,cAAc;AAGpB,MAAM,WAAW;AAEjB,MAAa,qBAAqB;CAAC;CAAM;CAAW;CAAmB;AAA2B;AAElG,IAAI,sBAA0C;AAE9C,SAAgB,eAAe,SAAwC;CACrE,sBAAsB,WAAW;AACnC;AAEA,SAAS,iBAA8B;CACrC,IAAI,CAAC,qBAAqB,sBAAsB,IAAI,YAAY;CAChE,OAAO;AACT;AAEA,SAAgB,0BAA0B,UAAiD,CAAC,GAAiB;CAC3G,QAAQ,OAAO,OAA+B,SAAuC;EACnF,MAAM,QAAQ,QAAQ,mBAAmB,eAAe;EACxD,MAAM,OAAO;EACb,MAAM,aAAa,MAAM,IAAI,WAAW;EACxC,IAAI,CAAC,cAAc,WAAW,SAAS,SACrC,MAAM,IAAI,0BAA0B,mCAAmC;EAEzE,IAAI,CAAC,qBAAqB,WAAW,QAAQ,GAC3C,MAAM,IAAI,0BAA0B,wEAAwE;EAE9G,MAAM,gBAAgB,2BAA2B,WAAW,QAAQ;EACpE,MAAM,QAAQ,MAAM,MAAM,UAAU,WAAW;EAC/C,IAAI,CAAC,OAAO,MAAM,IAAI,0BAA0B,8CAA8C;EAE9F,MAAM,UAAU,IAAI,QAAQ,iBAAiB,UAAU,MAAM,UAAU,KAAA,CAAS;EAChF,IAAI,MAAM,SAAS,IAAI,QAAQ,KAAK,OAAO,CAAC,CAAC,SAAS,OAAO,QAAQ,QAAQ,IAAI,KAAK,KAAK,CAAC;EAC5F,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,aAAa,GAAG,QAAQ,IAAI,KAAK,KAAK;EAChF,QAAQ,OAAO,eAAe;EAC9B,QAAQ,OAAO,WAAW;EAC1B,QAAQ,IAAI,iBAAiB,UAAU,OAAO;EAC9C,OAAO,MAAM,OAAO;GAAE,GAAG;GAAM;EAAQ,CAAC;CAC1C;AACF;AAEA,SAAgB,2BAA2B,QAA8B;CACvE,QAAQ,OAAO,OAA+B,SAAuC;EACnF,MAAM,UAAU,IAAI,QAAQ,iBAAiB,UAAU,MAAM,UAAU,KAAA,CAAS;EAChF,IAAI,MAAM,SAAS,IAAI,QAAQ,KAAK,OAAO,CAAC,CAAC,SAAS,OAAO,QAAQ,QAAQ,IAAI,KAAK,KAAK,CAAC;EAC5F,QAAQ,OAAO,eAAe;EAC9B,QAAQ,OAAO,WAAW;EAC1B,QAAQ,IAAI,iBAAiB,UAAU,QAAQ;EAC/C,OAAO,MAAM,OAAO;GAAE,GAAG;GAAM;EAAQ,CAAC;CAC1C;AACF;AAEA,SAAgB,mBACd,SACA,SACmB;CACnB,MAAM,YAAY,QAAQ,iBAAiB,IAAI,WAAW,CAAC,EAAE,SAAS;CAStE,OARiB,gBAAgB;EAC/B,QAAQ;EACR,SAAS;EACT,SAAS,QAAQ;EACjB,OAAO,YACF,0BAA0B,EAAE,iBAAiB,QAAQ,gBAAgB,CAAC,IACtE,2BAA2B,QAAQ,MAAM;CAChD,CACc,CAAC,CAAC,OAAO;AACzB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/code-sdk",
3
- "version": "1.5.2-alpha.1",
3
+ "version": "1.5.2-alpha.2",
4
4
  "description": "Mastra Code SDK: the agent core behind Mastra Code (everything except the TUI) — build your own UIs and surfaces on top of it",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -59,15 +59,15 @@
59
59
  "zod": "^4.3.6",
60
60
  "@mastra/agent-browser": "0.5.1",
61
61
  "@mastra/duckdb": "1.6.3",
62
- "@mastra/core": "1.63.1-alpha.1",
63
62
  "@mastra/fastembed": "1.3.0",
64
- "@mastra/libsql": "1.22.0",
65
- "@mastra/mcp": "1.17.2",
63
+ "@mastra/core": "1.63.1-alpha.2",
66
64
  "@mastra/github-signals": "0.3.0",
67
- "@mastra/memory": "1.28.1-alpha.0",
68
- "@mastra/parallel": "0.1.0",
65
+ "@mastra/libsql": "1.22.1-alpha.0",
66
+ "@mastra/memory": "1.28.1-alpha.1",
67
+ "@mastra/mcp": "1.17.2",
69
68
  "@mastra/observability": "1.17.4-alpha.0",
70
- "@mastra/pg": "1.22.0",
69
+ "@mastra/pg": "1.22.1-alpha.0",
70
+ "@mastra/parallel": "0.1.0",
71
71
  "@mastra/stagehand": "0.3.3",
72
72
  "@mastra/tavily": "1.1.1",
73
73
  "@mastra/schema-compat": "1.3.7"
@@ -81,9 +81,9 @@
81
81
  "typescript": "^6.0.3",
82
82
  "typescript-eslint": "^8.57.0",
83
83
  "vitest": "4.1.10",
84
- "@internal/types-builder": "0.0.102",
84
+ "@internal/lint": "0.0.127",
85
85
  "@internal/workspace-test-utils": "0.0.71",
86
- "@internal/lint": "0.0.127"
86
+ "@internal/types-builder": "0.0.102"
87
87
  },
88
88
  "engines": {
89
89
  "node": ">=22.19.0"