@genkit-ai/core
Version:
Genkit AI framework core libraries.
248 lines • 8.43 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var instrumentation_exports = {};
__export(instrumentation_exports, {
ATTR_PREFIX: () => ATTR_PREFIX,
SPAN_TYPE_ATTR: () => SPAN_TYPE_ATTR,
appendSpan: () => appendSpan,
disableOTelRootSpanDetection: () => disableOTelRootSpanDetection,
runInNewSpan: () => runInNewSpan,
setCustomMetadataAttribute: () => setCustomMetadataAttribute,
setCustomMetadataAttributes: () => setCustomMetadataAttributes,
spanMetadataAlsKey: () => spanMetadataAlsKey,
toDisplayPath: () => toDisplayPath
});
module.exports = __toCommonJS(instrumentation_exports);
var import_api = require("@opentelemetry/api");
var import_node_perf_hooks = require("node:perf_hooks");
var import_async_context = require("../async-context.js");
var import_tracing = require("../tracing.js");
const spanMetadataAlsKey = "core.tracing.instrumentation.span";
const ATTR_PREFIX = "genkit";
const SPAN_TYPE_ATTR = ATTR_PREFIX + ":type";
const TRACER_NAME = "genkit-tracer";
const TRACER_VERSION = "v1";
async function runInNewSpan(registryOrOprs, optsOrFn, fnMaybe) {
let opts;
let fn;
if (arguments.length === 3) {
opts = optsOrFn;
fn = fnMaybe;
} else {
opts = registryOrOprs;
fn = optsOrFn;
}
await (0, import_tracing.ensureBasicTelemetryInstrumentation)();
const tracer = import_api.trace.getTracer(TRACER_NAME, TRACER_VERSION);
const parentStep = (0, import_async_context.getAsyncContext)().getStore(spanMetadataAlsKey);
const isInRoot = parentStep?.metadata?.isRoot === true;
if (!parentStep) opts.metadata.isRoot ||= true;
const spanOptions = {
links: opts.links,
attributes: opts.labels
};
if (!isDisableRootSpanDetection()) {
spanOptions.root = opts.metadata.isRoot;
}
return await tracer.startActiveSpan(
opts.metadata.name,
spanOptions,
async (otSpan) => {
const spanContext = {
...parentStep,
metadata: opts.metadata,
labels: opts.labels
};
try {
opts.metadata.path = buildPath(
opts.metadata.name,
parentStep?.metadata?.path || "",
opts.labels
);
const isGenkitSpan = !!opts.labels?.[SPAN_TYPE_ATTR];
if (isGenkitSpan && parentStep) {
const parentIsGenkit = !!parentStep.labels?.[SPAN_TYPE_ATTR];
if (!parentIsGenkit && parentStep.spanId) {
otSpan.setAttribute(
ATTR_PREFIX + ":lastKnownParentSpanId",
parentStep.spanId
);
}
}
if (isGenkitSpan) {
spanContext.spanId = otSpan.spanContext().spanId;
}
const output = await (0, import_async_context.getAsyncContext)().run(
spanMetadataAlsKey,
spanContext,
() => fn(opts.metadata, otSpan, isInRoot)
);
if (opts.metadata.state !== "error") {
opts.metadata.state = "success";
}
recordPath(opts.metadata, spanContext);
return output;
} catch (e) {
recordPath(opts.metadata, spanContext, e);
opts.metadata.state = "error";
otSpan.setStatus({
code: import_api.SpanStatusCode.ERROR,
message: getErrorMessage(e)
});
if (e instanceof Error) {
otSpan.recordException(e);
}
if (typeof e === "object") {
if (!e.ignoreFailedSpan) {
opts.metadata.isFailureSource = true;
}
e.ignoreFailedSpan = true;
}
throw e;
} finally {
otSpan.setAttributes(metadataToAttributes(opts.metadata));
otSpan.end();
}
}
);
}
async function appendSpan(traceId, parentSpanId, metadata, labels) {
await (0, import_tracing.ensureBasicTelemetryInstrumentation)();
const tracer = import_api.trace.getTracer(TRACER_NAME, TRACER_VERSION);
const spanContext = import_api.trace.setSpanContext(import_api.ROOT_CONTEXT, {
traceId,
traceFlags: 1,
// sampled
spanId: parentSpanId
});
const span = tracer.startSpan(metadata.name, {}, spanContext);
span.setAttributes(metadataToAttributes(metadata));
if (labels) {
span.setAttributes(labels);
}
span.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 = (0, import_async_context.getAsyncContext)().getStore(spanMetadataAlsKey);
if (!step) {
throw new Error("running outside step context");
}
return step.metadata;
}
function buildPath(name, parentPath, labels) {
const stepType = labels && labels["genkit:type"] ? `,t:${labels["genkit:metadata:subtype"] === "flow" ? "flow" : labels["genkit:type"]}` : "";
return parentPath + `/{${name}${stepType}}`;
}
function recordPath(spanMeta, spanContext, err) {
const path = spanMeta.path || "";
const decoratedPath = decoratePathWithSubtype(spanMeta);
const paths = Array.from(spanContext?.paths || /* @__PURE__ */ new Set());
const status = err ? "failure" : "success";
if (!paths.some((p) => p.path.startsWith(path) && p.status === status)) {
const now = import_node_perf_hooks.performance.now();
const start = spanContext?.timestamp || now;
spanContext?.paths?.add({
path: decoratedPath,
error: err?.name,
latency: now - start,
status
});
}
spanMeta.path = decoratedPath;
}
function decoratePathWithSubtype(metadata) {
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 = `{${pathComponents.at(-1)?.slice(0, -1)}${stepSubtype}}`;
return root + decoratedStep;
}
const rootSpanDetectionKey = "__genkit_disableRootSpanDetection";
function isDisableRootSpanDetection() {
return global[rootSpanDetectionKey] === true;
}
function disableOTelRootSpanDetection() {
global[rootSpanDetectionKey] = true;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ATTR_PREFIX,
SPAN_TYPE_ATTR,
appendSpan,
disableOTelRootSpanDetection,
runInNewSpan,
setCustomMetadataAttribute,
setCustomMetadataAttributes,
spanMetadataAlsKey,
toDisplayPath
});
//# sourceMappingURL=instrumentation.js.map