UNPKG

@genkit-ai/core

Version:

Genkit AI framework core libraries.

192 lines 6.01 kB
import { __async } from "../chunk-XEFTB2OF.mjs"; import { SpanStatusCode, trace } from "@opentelemetry/api"; import { AsyncLocalStorage } from "node:async_hooks"; import { performance } from "node:perf_hooks"; const spanMetadataAls = new AsyncLocalStorage(); const traceMetadataAls = new AsyncLocalStorage(); const ATTR_PREFIX = "genkit"; const SPAN_TYPE_ATTR = ATTR_PREFIX + ":type"; const TRACER_NAME = "genkit-tracer"; const TRACER_VERSION = "v1"; function newTrace(opts, fn) { return __async(this, null, function* () { const isRoot = traceMetadataAls.getStore() ? false : true; const traceMetadata = traceMetadataAls.getStore() || { paths: /* @__PURE__ */ new Set(), timestamp: performance.now() }; if (opts.labels && opts.labels[SPAN_TYPE_ATTR] === "flow") { traceMetadata.flowName = opts.name; } return yield traceMetadataAls.run( traceMetadata, () => runInNewSpan( { metadata: { name: opts.name, isRoot }, labels: opts.labels, links: opts.links }, (metadata, otSpan) => __async(this, null, function* () { return yield fn(metadata, otSpan); }) ) ); }); } function runInNewSpan(opts, fn) { return __async(this, null, function* () { const tracer = trace.getTracer(TRACER_NAME, TRACER_VERSION); const parentStep = spanMetadataAls.getStore(); const isInRoot = (parentStep == null ? void 0 : parentStep.isRoot) === true; return yield tracer.startActiveSpan( opts.metadata.name, { links: opts.links, root: opts.metadata.isRoot }, (otSpan) => __async(this, null, function* () { if (opts.labels) otSpan.setAttributes(opts.labels); try { opts.metadata.path = buildPath( opts.metadata.name, (parentStep == null ? void 0 : parentStep.path) || "", opts.labels ); const output = yield spanMetadataAls.run( opts.metadata, () => fn(opts.metadata, otSpan, isInRoot) ); if (opts.metadata.state !== "error") { opts.metadata.state = "success"; } recordPath(opts.metadata); return output; } catch (e) { recordPath(opts.metadata, e); opts.metadata.state = "error"; otSpan.setStatus({ code: SpanStatusCode.ERROR, message: getErrorMessage(e) }); if (e instanceof Error) { otSpan.recordException(e); } throw e; } finally { otSpan.setAttributes(metadataToAttributes(opts.metadata)); otSpan.end(); } }) ); }); } function getErrorMessage(e) { if (e instanceof Error) { return e.message; } return `${e}`; } function metadataToAttributes(metadata) { const out = {}; Object.keys(metadata).forEach((key) => { if (key === "metadata" && typeof metadata[key] === "object" && metadata.metadata) { Object.entries(metadata.metadata).forEach(([metaKey, value]) => { out[ATTR_PREFIX + ":metadata:" + metaKey] = value; }); } else if (key === "input" || typeof metadata[key] === "object") { out[ATTR_PREFIX + ":" + key] = JSON.stringify(metadata[key]); } else { out[ATTR_PREFIX + ":" + key] = metadata[key]; } }); return out; } function setCustomMetadataAttribute(key, value) { const currentStep = getCurrentSpan(); if (!currentStep) { return; } if (!currentStep.metadata) { currentStep.metadata = {}; } currentStep.metadata[key] = value; } function setCustomMetadataAttributes(values) { const currentStep = getCurrentSpan(); if (!currentStep) { return; } if (!currentStep.metadata) { currentStep.metadata = {}; } for (const [key, value] of Object.entries(values)) { currentStep.metadata[key] = value; } } function toDisplayPath(path) { const pathPartRegex = /\{([^\,}]+),[^\}]+\}/g; return Array.from(path.matchAll(pathPartRegex), (m) => m[1]).join(" > "); } function getCurrentSpan() { const step = spanMetadataAls.getStore(); if (!step) { throw new Error("running outside step context"); } return step; } function buildPath(name, parentPath, labels) { const stepType = labels && labels["genkit:type"] ? `,t:${labels["genkit:type"]}` : ""; return parentPath + `/{${name}${stepType}}`; } function recordPath(spanMeta, err) { var _a, _b, _c, _d; const path = spanMeta.path || ""; const decoratedPath = decoratePathWithSubtype(spanMeta); const paths = Array.from( ((_a = traceMetadataAls.getStore()) == null ? void 0 : _a.paths) || /* @__PURE__ */ new Set() ); const status = err ? "failure" : "success"; if (!paths.some((p) => p.path.startsWith(path) && p.status === status)) { const now = performance.now(); const start = ((_b = traceMetadataAls.getStore()) == null ? void 0 : _b.timestamp) || now; (_d = (_c = traceMetadataAls.getStore()) == null ? void 0 : _c.paths) == null ? void 0 : _d.add({ path: decoratedPath, error: err == null ? void 0 : err.name, latency: now - start, status }); } spanMeta.path = decoratedPath; } function decoratePathWithSubtype(metadata) { var _a; if (!metadata.path) { return ""; } const pathComponents = metadata.path.split("}/{"); if (pathComponents.length == 1) { return metadata.path; } const stepSubtype = metadata.metadata && metadata.metadata["subtype"] ? `,s:${metadata.metadata["subtype"]}` : ""; const root = `${pathComponents.slice(0, -1).join("}/{")}}/`; const decoratedStep = `{${(_a = pathComponents.at(-1)) == null ? void 0 : _a.slice(0, -1)}${stepSubtype}}`; return root + decoratedStep; } export { ATTR_PREFIX, SPAN_TYPE_ATTR, newTrace, runInNewSpan, setCustomMetadataAttribute, setCustomMetadataAttributes, spanMetadataAls, toDisplayPath, traceMetadataAls }; //# sourceMappingURL=instrumentation.mjs.map