@genkit-ai/core
Version:
Genkit AI framework core libraries.
192 lines • 6.01 kB
JavaScript
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