@genkit-ai/google-cloud
Version:
Genkit AI framework plugin for Google Cloud Platform including Firestore trace/state store and deployment helpers for Cloud Functions for Firebase.
326 lines • 11.6 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 generate_exports = {};
__export(generate_exports, {
generateTelemetry: () => generateTelemetry
});
module.exports = __toCommonJS(generate_exports);
var import_api = require("@opentelemetry/api");
var import_crypto = require("crypto");
var import_genkit = require("genkit");
var import_logging = require("genkit/logging");
var import_tracing = require("genkit/tracing");
var import_metrics = require("../metrics.js");
var import_utils = require("../utils.js");
class GenerateTelemetry {
/**
* Wraps the declared metrics in a Genkit-specific, internal namespace.
*/
_N = import_metrics.internalMetricNamespaceWrap.bind(null, "ai");
actionCounter = new import_metrics.MetricCounter(this._N("generate/requests"), {
description: "Counts calls to genkit generate actions.",
valueType: import_api.ValueType.INT
});
latencies = new import_metrics.MetricHistogram(this._N("generate/latency"), {
description: "Latencies when interacting with a Genkit model.",
valueType: import_api.ValueType.DOUBLE,
unit: "ms"
});
inputCharacters = new import_metrics.MetricCounter(
this._N("generate/input/characters"),
{
description: "Counts input characters to any Genkit model.",
valueType: import_api.ValueType.INT
}
);
inputTokens = new import_metrics.MetricCounter(this._N("generate/input/tokens"), {
description: "Counts input tokens to a Genkit model.",
valueType: import_api.ValueType.INT
});
inputImages = new import_metrics.MetricCounter(this._N("generate/input/images"), {
description: "Counts input images to a Genkit model.",
valueType: import_api.ValueType.INT
});
outputCharacters = new import_metrics.MetricCounter(
this._N("generate/output/characters"),
{
description: "Counts output characters from a Genkit model.",
valueType: import_api.ValueType.INT
}
);
outputTokens = new import_metrics.MetricCounter(this._N("generate/output/tokens"), {
description: "Counts output tokens from a Genkit model.",
valueType: import_api.ValueType.INT
});
thinkingTokens = new import_metrics.MetricCounter(
this._N("generate/thinking/tokens"),
{
description: "Counts thinking tokens from a Genkit model.",
valueType: import_api.ValueType.INT
}
);
outputImages = new import_metrics.MetricCounter(this._N("generate/output/images"), {
description: "Count output images from a Genkit model.",
valueType: import_api.ValueType.INT
});
tick(span, logInputAndOutput, projectId) {
const attributes = span.attributes;
const modelName = (0, import_utils.truncate)(attributes["genkit:name"], 1024);
const path = attributes["genkit:path"] || "";
const input = "genkit:input" in attributes ? JSON.parse(
attributes["genkit:input"]
) : void 0;
const output = "genkit:output" in attributes ? JSON.parse(
attributes["genkit:output"]
) : void 0;
const errName = (0, import_utils.extractErrorName)(span.events);
let featureName = (0, import_utils.truncate)(
attributes["genkit:metadata:flow:name"] || (0, import_utils.extractOuterFeatureNameFromPath)(path)
);
if (!featureName || featureName === "<unknown>") {
featureName = "generate";
}
const sessionId = attributes["genkit:sessionId"];
const threadName = attributes["genkit:threadName"];
if (input) {
this.recordGenerateActionMetrics(modelName, featureName, path, {
response: output,
errName
});
this.recordGenerateActionConfigLogs(
span,
modelName,
featureName,
path,
input,
projectId,
sessionId,
threadName
);
if (logInputAndOutput) {
this.recordGenerateActionInputLogs(
span,
modelName,
featureName,
path,
input,
projectId,
sessionId,
threadName
);
}
}
if (output && logInputAndOutput) {
this.recordGenerateActionOutputLogs(
span,
modelName,
featureName,
path,
output,
projectId,
sessionId,
threadName
);
}
}
recordGenerateActionMetrics(modelName, featureName, path, opts) {
this.doRecordGenerateActionMetrics(modelName, opts.response?.usage || {}, {
featureName,
path,
latencyMs: opts.response?.latencyMs,
errName: opts.errName,
source: "ts",
sourceVersion: import_genkit.GENKIT_VERSION
});
}
recordGenerateActionConfigLogs(span, model, featureName, qualifiedPath, input, projectId, sessionId, threadName) {
const path = (0, import_utils.truncatePath)((0, import_tracing.toDisplayPath)(qualifiedPath));
const sharedMetadata = {
...(0, import_utils.createCommonLogAttributes)(span, projectId),
model,
path,
qualifiedPath,
featureName,
sessionId,
threadName
};
import_logging.logger.logStructured(`Config[${path}, ${model}]`, {
...sharedMetadata,
maxOutputTokens: input.config?.maxOutputTokens,
stopSequences: input.config?.stopSequences,
// array
source: "ts",
sourceVersion: import_genkit.GENKIT_VERSION
});
}
recordGenerateActionInputLogs(span, model, featureName, qualifiedPath, input, projectId, sessionId, threadName) {
const path = (0, import_utils.truncatePath)((0, import_tracing.toDisplayPath)(qualifiedPath));
const sharedMetadata = {
...(0, import_utils.createCommonLogAttributes)(span, projectId),
model,
path,
qualifiedPath,
featureName,
sessionId,
threadName
};
const messages = input.messages.length;
input.messages.forEach((msg, msgIdx) => {
const parts = msg.content.length;
msg.content.forEach((part, partIdx) => {
const partCounts = this.toPartCounts(partIdx, parts, msgIdx, messages);
import_logging.logger.logStructured(`Input[${path}, ${model}] ${partCounts}`, {
...sharedMetadata,
content: this.toPartLogContent(part),
role: msg.role,
partIndex: partIdx,
totalParts: parts,
messageIndex: msgIdx,
totalMessages: messages
});
});
});
}
recordGenerateActionOutputLogs(span, model, featureName, qualifiedPath, output, projectId, sessionId, threadName) {
const path = (0, import_utils.truncatePath)((0, import_tracing.toDisplayPath)(qualifiedPath));
const sharedMetadata = {
...(0, import_utils.createCommonLogAttributes)(span, projectId),
model,
path,
qualifiedPath,
featureName,
sessionId,
threadName
};
const message = output.message || output.candidates?.[0]?.message;
if (message?.content) {
const parts = message.content.length;
message.content.forEach((part, partIdx) => {
const partCounts = this.toPartCounts(partIdx, parts, 0, 1);
const initial = output.finishMessage ? { finishMessage: (0, import_utils.truncate)(output.finishMessage) } : {};
import_logging.logger.logStructured(`Output[${path}, ${model}] ${partCounts}`, {
...initial,
...sharedMetadata,
content: this.toPartLogContent(part),
role: message.role,
partIndex: partIdx,
totalParts: parts,
candidateIndex: 0,
totalCandidates: 1,
messageIndex: 0,
finishReason: output.finishReason
});
});
}
}
toPartCounts(partOrdinal, parts, msgOrdinal, messages) {
if (parts > 1 && messages > 1) {
return `(part ${this.xOfY(partOrdinal, parts)} in message ${this.xOfY(
msgOrdinal,
messages
)})`;
}
if (parts > 1) {
return `(part ${this.xOfY(partOrdinal, parts)})`;
}
if (messages > 1) {
return `(message ${this.xOfY(msgOrdinal, messages)})`;
}
return "";
}
xOfY(x, y) {
return `${x + 1} of ${y}`;
}
toPartLogContent(part) {
if (part.text) {
return (0, import_utils.truncate)(part.text);
}
if (part.data) {
return (0, import_utils.truncate)(JSON.stringify(part.data));
}
if (part.media) {
return this.toPartLogMedia(part);
}
if (part.toolRequest) {
return this.toPartLogToolRequest(part);
}
if (part.toolResponse) {
return this.toPartLogToolResponse(part);
}
if (part.custom) {
return (0, import_utils.truncate)(JSON.stringify(part.custom));
}
return "<unknown format>";
}
toPartLogMedia(part) {
if (part.media.url.startsWith("data:")) {
const splitIdx = part.media.url.indexOf("base64,");
if (splitIdx < 0) {
return "<unknown media format>";
}
const prefix = part.media.url.substring(0, splitIdx + 7);
const hashedContent = (0, import_crypto.createHash)("sha256").update(part.media.url.substring(splitIdx + 7)).digest("hex");
return `${prefix}<sha256(${hashedContent})>`;
}
return (0, import_utils.truncate)(part.media.url);
}
toPartLogToolRequest(part) {
const inputText = typeof part.toolRequest.input === "string" ? part.toolRequest.input : JSON.stringify(part.toolRequest.input);
return (0, import_utils.truncate)(
`Tool request: ${part.toolRequest.name}, ref: ${part.toolRequest.ref}, input: ${inputText}`
);
}
toPartLogToolResponse(part) {
const outputText = typeof part.toolResponse.output === "string" ? part.toolResponse.output : JSON.stringify(part.toolResponse.output);
return (0, import_utils.truncate)(
`Tool response: ${part.toolResponse.name}, ref: ${part.toolResponse.ref}, output: ${outputText}`
);
}
/**
* Records all metrics associated with performing a GenerateAction.
*/
doRecordGenerateActionMetrics(modelName, usage, dimensions) {
const shared = {
modelName,
featureName: dimensions.featureName,
path: dimensions.path,
source: dimensions.source,
sourceVersion: dimensions.sourceVersion,
status: dimensions.errName ? "failure" : "success"
};
this.actionCounter.add(1, {
error: dimensions.errName,
...shared
});
this.latencies.record(dimensions.latencyMs, shared);
this.inputTokens.add(usage.inputTokens, shared);
this.inputCharacters.add(usage.inputCharacters, shared);
this.inputImages.add(usage.inputImages, shared);
this.outputTokens.add(usage.outputTokens, shared);
this.outputCharacters.add(usage.outputCharacters, shared);
this.outputImages.add(usage.outputImages, shared);
this.thinkingTokens.add(usage.thoughtsTokens, shared);
}
}
const generateTelemetry = new GenerateTelemetry();
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
generateTelemetry
});
//# sourceMappingURL=generate.js.map