{"version":3,"sources":["../../src/telemetry/engagement.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ValueType, type Attributes } from '@opentelemetry/api';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-base';\nimport { GENKIT_VERSION } from 'genkit';\nimport { logger } from 'genkit/logging';\nimport {\n  MetricCounter,\n  internalMetricNamespaceWrap,\n  type Telemetry,\n} from '../metrics.js';\nimport { createCommonLogAttributes, truncate } from '../utils.js';\n\nclass EngagementTelemetry implements Telemetry {\n  /**\n   * Wraps the declared metrics in a Genkit-specific, internal namespace.\n   */\n  private _N = internalMetricNamespaceWrap.bind(null, 'engagement');\n\n  private feedbackCounter = new MetricCounter(this._N('feedback'), {\n    description: 'Counts calls to genkit flows.',\n    valueType: ValueType.INT,\n  });\n\n  private acceptanceCounter = new MetricCounter(this._N('acceptance'), {\n    description: 'Tracks unique flow paths per flow.',\n    valueType: ValueType.INT,\n  });\n\n  tick(\n    span: ReadableSpan,\n    logInputAndOutput: boolean,\n    projectId?: string\n  ): void {\n    const subtype = span.attributes['genkit:metadata:subtype'] as string;\n\n    if (subtype === 'userFeedback') {\n      this.writeUserFeedback(span, projectId);\n      return;\n    }\n\n    if (subtype === 'userAcceptance') {\n      this.writeUserAcceptance(span, projectId);\n      return;\n    }\n\n    logger.warn(`Unknown user engagement subtype: ${subtype}`);\n  }\n\n  private writeUserFeedback(span: ReadableSpan, projectId?: string) {\n    const attributes = span.attributes;\n    const name = this.extractTraceName(attributes);\n\n    const dimensions = {\n      name,\n      value: attributes['genkit:metadata:feedbackValue'],\n      hasText: !!attributes['genkit:metadata:textFeedback'],\n      source: 'ts',\n      sourceVersion: GENKIT_VERSION,\n    };\n    this.feedbackCounter.add(1, dimensions);\n\n    const metadata = {\n      ...createCommonLogAttributes(span, projectId),\n      feedbackValue: attributes['genkit:metadata:feedbackValue'],\n    };\n    if (attributes['genkit:metadata:textFeedback']) {\n      metadata['textFeedback'] = truncate(\n        attributes['genkit:metadata:textFeedback'] as string\n      );\n    }\n    logger.logStructured(`UserFeedback[${name}]`, metadata);\n  }\n\n  private writeUserAcceptance(span: ReadableSpan, projectId?: string) {\n    const attributes = span.attributes;\n    const name = this.extractTraceName(attributes);\n\n    const dimensions = {\n      name,\n      value: attributes['genkit:metadata:acceptanceValue'],\n      source: 'ts',\n      sourceVersion: GENKIT_VERSION,\n    };\n    this.acceptanceCounter.add(1, dimensions);\n\n    const metadata = {\n      ...createCommonLogAttributes(span, projectId),\n      acceptanceValue: attributes['genkit:metadata:acceptanceValue'],\n    };\n    logger.logStructured(`UserAcceptance[${name}]`, metadata);\n  }\n\n  private extractTraceName(attributes: Attributes) {\n    const path = attributes['genkit:path'] as string;\n    if (!path || path === '<unknown>') {\n      return '<unknown>';\n    }\n\n    const name = path.match('/{(.+)}+');\n    return name ? name[1] : '<unknown>';\n  }\n}\n\nconst engagementTelemetry = new EngagementTelemetry();\nexport { engagementTelemetry };\n"],"mappings":"AAgBA,SAAS,iBAAkC;AAE3C,SAAS,sBAAsB;AAC/B,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AACP,SAAS,2BAA2B,gBAAgB;AAEpD,MAAM,oBAAyC;AAAA;AAAA;AAAA;AAAA,EAIrC,KAAK,4BAA4B,KAAK,MAAM,YAAY;AAAA,EAExD,kBAAkB,IAAI,cAAc,KAAK,GAAG,UAAU,GAAG;AAAA,IAC/D,aAAa;AAAA,IACb,WAAW,UAAU;AAAA,EACvB,CAAC;AAAA,EAEO,oBAAoB,IAAI,cAAc,KAAK,GAAG,YAAY,GAAG;AAAA,IACnE,aAAa;AAAA,IACb,WAAW,UAAU;AAAA,EACvB,CAAC;AAAA,EAED,KACE,MACA,mBACA,WACM;AACN,UAAM,UAAU,KAAK,WAAW,yBAAyB;AAEzD,QAAI,YAAY,gBAAgB;AAC9B,WAAK,kBAAkB,MAAM,SAAS;AACtC;AAAA,IACF;AAEA,QAAI,YAAY,kBAAkB;AAChC,WAAK,oBAAoB,MAAM,SAAS;AACxC;AAAA,IACF;AAEA,WAAO,KAAK,oCAAoC,OAAO,EAAE;AAAA,EAC3D;AAAA,EAEQ,kBAAkB,MAAoB,WAAoB;AAChE,UAAM,aAAa,KAAK;AACxB,UAAM,OAAO,KAAK,iBAAiB,UAAU;AAE7C,UAAM,aAAa;AAAA,MACjB;AAAA,MACA,OAAO,WAAW,+BAA+B;AAAA,MACjD,SAAS,CAAC,CAAC,WAAW,8BAA8B;AAAA,MACpD,QAAQ;AAAA,MACR,eAAe;AAAA,IACjB;AACA,SAAK,gBAAgB,IAAI,GAAG,UAAU;AAEtC,UAAM,WAAW;AAAA,MACf,GAAG,0BAA0B,MAAM,SAAS;AAAA,MAC5C,eAAe,WAAW,+BAA+B;AAAA,IAC3D;AACA,QAAI,WAAW,8BAA8B,GAAG;AAC9C,eAAS,cAAc,IAAI;AAAA,QACzB,WAAW,8BAA8B;AAAA,MAC3C;AAAA,IACF;AACA,WAAO,cAAc,gBAAgB,IAAI,KAAK,QAAQ;AAAA,EACxD;AAAA,EAEQ,oBAAoB,MAAoB,WAAoB;AAClE,UAAM,aAAa,KAAK;AACxB,UAAM,OAAO,KAAK,iBAAiB,UAAU;AAE7C,UAAM,aAAa;AAAA,MACjB;AAAA,MACA,OAAO,WAAW,iCAAiC;AAAA,MACnD,QAAQ;AAAA,MACR,eAAe;AAAA,IACjB;AACA,SAAK,kBAAkB,IAAI,GAAG,UAAU;AAExC,UAAM,WAAW;AAAA,MACf,GAAG,0BAA0B,MAAM,SAAS;AAAA,MAC5C,iBAAiB,WAAW,iCAAiC;AAAA,IAC/D;AACA,WAAO,cAAc,kBAAkB,IAAI,KAAK,QAAQ;AAAA,EAC1D;AAAA,EAEQ,iBAAiB,YAAwB;AAC/C,UAAM,OAAO,WAAW,aAAa;AACrC,QAAI,CAAC,QAAQ,SAAS,aAAa;AACjC,aAAO;AAAA,IACT;AAEA,UAAM,OAAO,KAAK,MAAM,UAAU;AAClC,WAAO,OAAO,KAAK,CAAC,IAAI;AAAA,EAC1B;AACF;AAEA,MAAM,sBAAsB,IAAI,oBAAoB;","names":[]}