UNPKG

@mastra/core

Version:
189 lines (183 loc) • 6.65 kB
'use strict'; var fs = require('fs'); var os = require('os'); var path = require('path'); var crypto = require('crypto'); var posthogNode = require('posthog-node'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var os__default = /*#__PURE__*/_interopDefault(os); var path__default = /*#__PURE__*/_interopDefault(path); var POSTHOG_API_KEY = "phc_SBLpZVAB6jmHOct9CABq3PF0Yn5FU3G2FgT4xUr2XrT"; var POSTHOG_HOST = "https://us.posthog.com"; var TRUTHY_DISABLED_VALUES = /* @__PURE__ */ new Set(["1", "true", "yes"]); var client = null; function isEETelemetryEnabled() { const value = process.env["MASTRA_TELEMETRY_DISABLED"]; if (!value) { return true; } return !TRUTHY_DISABLED_VALUES.has(value.trim().toLowerCase()); } function hashTelemetryValue(value) { return crypto.createHash("sha256").update(value).digest("hex"); } function getHashedHostname() { return hashTelemetryValue(os__default.default.hostname() || "unknown-host").slice(0, 16); } function getEETelemetryFallbackDistinctId() { return `mastra-${getHashedHostname()}`; } function getClient() { if (!isEETelemetryEnabled()) { return null; } if (!client) { client = new posthogNode.PostHog(POSTHOG_API_KEY, { host: POSTHOG_HOST, flushAt: 1, flushInterval: 0, disableGeoip: false }); } return client; } function getSystemProperties() { return { os: process.platform, os_version: os__default.default.release(), node_version: process.version, platform: process.arch, machine_id: getHashedHostname(), mastra_version: process.env["npm_package_version"] || "unknown" }; } function captureTelemetryEvent(event, distinctId, properties) { try { const posthog = getClient(); if (!posthog) { return; } posthog.capture({ distinctId: distinctId || getEETelemetryFallbackDistinctId(), event, properties: { ...getSystemProperties(), ...properties } }); } catch { } } // src/telemetry/usage-telemetry.ts var INPUT_TOKENS_METRIC = "mastra_model_total_input_tokens"; var OUTPUT_TOKENS_METRIC = "mastra_model_total_output_tokens"; var BREAKDOWN_LIMIT = 200; var USAGE_TELEMETRY_EVENT = "mastra_model_token_usage"; function getDefaultCursorPath() { return path__default.default.join(os__default.default.homedir(), ".mastra", "usage-telemetry.json"); } function readCursors(cursorPath) { try { const parsed = JSON.parse(fs.readFileSync(cursorPath, "utf-8")); if (parsed && typeof parsed === "object" && parsed.projects && typeof parsed.projects === "object") { return { projects: parsed.projects }; } } catch { } return { projects: {} }; } function readCursor(cursorPath, projectId) { const value = readCursors(cursorPath).projects[projectId]; if (!value) { return void 0; } const date = new Date(value); return Number.isNaN(date.getTime()) ? void 0 : date; } function writeCursor(cursorPath, projectId, syncedAt) { const cursors = readCursors(cursorPath); cursors.projects[projectId] = syncedAt.toISOString(); fs.mkdirSync(path__default.default.dirname(cursorPath), { recursive: true }); fs.writeFileSync(cursorPath, JSON.stringify(cursors)); } function applyBreakdown(rows, response, field) { for (const group of response.groups) { const provider = group.dimensions.provider ?? null; const model = group.dimensions.model ?? null; const key = `${provider}\0${model}`; let row = rows.get(key); if (!row) { row = { provider, model, inputTokens: 0, outputTokens: 0, totalInputTokens: 0, totalOutputTokens: 0 }; rows.set(key, row); } row[field] += group.value ?? 0; } } async function syncUsageTelemetry(mastra, options = {}) { try { if (!isEETelemetryEnabled()) { return; } const observability = mastra.getStorage()?.stores?.observability; if (!observability || typeof observability.getMetricBreakdown !== "function") { return; } const projectRoot = process.env.MASTRA_PROJECT_ROOT || process.cwd(); const projectId = hashTelemetryValue(projectRoot).slice(0, 16); const cursorPath = options.cursorPath ?? getDefaultCursorPath(); const lastSyncedAt = readCursor(cursorPath, projectId); const now = options.now ?? /* @__PURE__ */ new Date(); if (lastSyncedAt && lastSyncedAt.getTime() >= now.getTime()) { return; } const baseArgs = { groupBy: ["provider", "model"], aggregation: "sum", limit: BREAKDOWN_LIMIT }; const deltaFilters = { timestamp: { ...lastSyncedAt ? { start: lastSyncedAt, startExclusive: true } : {}, end: now } }; const totalFilters = { timestamp: { end: now } }; const [inputDelta, outputDelta, inputTotal, outputTotal] = await Promise.all([ observability.getMetricBreakdown({ ...baseArgs, name: [INPUT_TOKENS_METRIC], filters: deltaFilters }), observability.getMetricBreakdown({ ...baseArgs, name: [OUTPUT_TOKENS_METRIC], filters: deltaFilters }), observability.getMetricBreakdown({ ...baseArgs, name: [INPUT_TOKENS_METRIC], filters: totalFilters }), observability.getMetricBreakdown({ ...baseArgs, name: [OUTPUT_TOKENS_METRIC], filters: totalFilters }) ]); const rows = /* @__PURE__ */ new Map(); applyBreakdown(rows, inputDelta, "inputTokens"); applyBreakdown(rows, outputDelta, "outputTokens"); applyBreakdown(rows, inputTotal, "totalInputTokens"); applyBreakdown(rows, outputTotal, "totalOutputTokens"); const distinctId = process.env.MASTRA_CLI_DISTINCT_ID || void 0; const command = process.env.MASTRA_TELEMETRY_COMMAND || "server"; const nodeEnv = process.env.NODE_ENV || "development"; const isFirstSync = !lastSyncedAt; for (const row of rows.values()) { if (row.inputTokens <= 0 && row.outputTokens <= 0) { continue; } captureTelemetryEvent(USAGE_TELEMETRY_EVENT, distinctId, { provider: row.provider, model: row.model, input_tokens: row.inputTokens, output_tokens: row.outputTokens, total_input_tokens: row.totalInputTokens, total_output_tokens: row.totalOutputTokens, command, node_env: nodeEnv, project_id: projectId, is_first_sync: isFirstSync, window_start: lastSyncedAt?.toISOString() ?? null, window_end: now.toISOString() }); } writeCursor(cursorPath, projectId, now); } catch { } } exports.USAGE_TELEMETRY_EVENT = USAGE_TELEMETRY_EVENT; exports.syncUsageTelemetry = syncUsageTelemetry; //# sourceMappingURL=index.cjs.map //# sourceMappingURL=index.cjs.map