@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.
1 lines • 7.31 kB
Source Map (JSON)
{"version":3,"sources":["../src/utils.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 { TraceFlags } from '@opentelemetry/api';\nimport type { ReadableSpan, TimedEvent } from '@opentelemetry/sdk-trace-base';\nimport { resolveCurrentPrincipal } from './auth.js';\n\n/**\n * The maximum length (in characters) of a logged input or output.\n * This limit exists to align the logs with GCP logging size limits.\n * */\nconst MAX_LOG_CONTENT_CHARS = 128_000;\n\n/**\n * The maximum length (in characters) of a flow path.\n */\nconst MAX_PATH_CHARS = 4096;\n\nexport function extractOuterFlowNameFromPath(path: string) {\n if (!path || path === '<unknown>') {\n return '<unknown>';\n }\n\n const flowName = path.match('/{(.+),t:flow}+');\n return flowName ? flowName[1] : '<unknown>';\n}\n\nexport function truncate(\n text: string,\n limit: number = MAX_LOG_CONTENT_CHARS\n): string {\n return text ? text.substring(0, limit) : text;\n}\n\nexport function truncatePath(path: string) {\n return truncate(path, MAX_PATH_CHARS);\n}\n\n/**\n * Extract first feature name from a path\n * e.g. for /{myFlow,t:flow}/{myStep,t:flowStep}/{googleai/gemini-pro,t:action,s:model}\n * returns \"myFlow\"\n */\nexport function extractOuterFeatureNameFromPath(path: string) {\n if (!path || path === '<unknown>') {\n return '<unknown>';\n }\n const first = path.split('/')[1];\n const featureName = first?.match(\n '{(.+),t:(flow|action|prompt|dotprompt|helper)'\n );\n return featureName ? featureName[1] : '<unknown>';\n}\n\nexport function extractErrorName(events: TimedEvent[]): string | undefined {\n return events\n .filter((event) => event.name === 'exception')\n .map((event) => {\n const attributes = event.attributes;\n return attributes\n ? truncate(attributes['exception.type'] as string, 1024)\n : '<unknown>';\n })\n .at(0);\n}\n\nexport function extractErrorMessage(events: TimedEvent[]): string | undefined {\n return events\n .filter((event) => event.name === 'exception')\n .map((event) => {\n const attributes = event.attributes;\n return attributes\n ? truncate(attributes['exception.message'] as string, 4096)\n : '<unknown>';\n })\n .at(0);\n}\n\nexport function extractErrorStack(events: TimedEvent[]): string | undefined {\n return events\n .filter((event) => event.name === 'exception')\n .map((event) => {\n const attributes = event.attributes;\n return attributes\n ? truncate(attributes['exception.stacktrace'] as string, 32_768)\n : '<unknown>';\n })\n .at(0);\n}\n\nexport function createCommonLogAttributes(\n span: ReadableSpan,\n projectId?: string\n) {\n const spanContext = span.spanContext();\n const isSampled = !!(spanContext.traceFlags & TraceFlags.SAMPLED);\n return {\n 'logging.googleapis.com/spanId': spanContext.spanId,\n 'logging.googleapis.com/trace': `projects/${projectId}/traces/${spanContext.traceId}`,\n 'logging.googleapis.com/trace_sampled': isSampled ? '1' : '0',\n };\n}\n\nexport function requestDenied(\n err: Error & {\n code?: number;\n statusDetails?: Record<string, any>[];\n }\n) {\n return err.code === 7;\n}\n\nexport function loggingDenied(\n err: Error & {\n code?: number;\n statusDetails?: Record<string, any>[];\n }\n) {\n return (\n requestDenied(err) &&\n err.statusDetails?.some((details) => {\n return details?.metadata?.permission === 'logging.logEntries.create';\n })\n );\n}\n\nexport function tracingDenied(\n err: Error & {\n code?: number;\n statusDetails?: Record<string, any>[];\n }\n) {\n // Looks like we don't get status details like we do with logging\n return requestDenied(err);\n}\n\nexport function metricsDenied(\n err: Error & {\n code?: number;\n statusDetails?: Record<string, any>[];\n }\n) {\n // Looks like we don't get status details like we do with logging\n return requestDenied(err);\n}\n\nexport async function permissionDeniedHelpText(role: string) {\n const principal = await resolveCurrentPrincipal();\n return `Add the role '${role}' to your Service Account in the IAM & Admin page on the Google Cloud console, or use the following command:\\n\\ngcloud projects add-iam-policy-binding ${principal.projectId ?? '${PROJECT_ID}'} \\\\\\n --member=serviceAccount:${principal.serviceAccountEmail || '${SERVICE_ACCT}'} \\\\\\n --role=${role}`;\n}\n\nexport async function loggingDeniedHelpText() {\n return permissionDeniedHelpText('roles/logging.logWriter');\n}\n\nexport async function tracingDeniedHelpText() {\n return permissionDeniedHelpText('roles/cloudtrace.agent');\n}\n\nexport async function metricsDeniedHelpText() {\n return permissionDeniedHelpText('roles/monitoring.metricWriter');\n}\n"],"mappings":"AAgBA,SAAS,kBAAkB;AAE3B,SAAS,+BAA+B;AAMxC,MAAM,wBAAwB;AAK9B,MAAM,iBAAiB;AAEhB,SAAS,6BAA6B,MAAc;AACzD,MAAI,CAAC,QAAQ,SAAS,aAAa;AACjC,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,KAAK,MAAM,iBAAiB;AAC7C,SAAO,WAAW,SAAS,CAAC,IAAI;AAClC;AAEO,SAAS,SACd,MACA,QAAgB,uBACR;AACR,SAAO,OAAO,KAAK,UAAU,GAAG,KAAK,IAAI;AAC3C;AAEO,SAAS,aAAa,MAAc;AACzC,SAAO,SAAS,MAAM,cAAc;AACtC;AAOO,SAAS,gCAAgC,MAAc;AAC5D,MAAI,CAAC,QAAQ,SAAS,aAAa;AACjC,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,KAAK,MAAM,GAAG,EAAE,CAAC;AAC/B,QAAM,cAAc,OAAO;AAAA,IACzB;AAAA,EACF;AACA,SAAO,cAAc,YAAY,CAAC,IAAI;AACxC;AAEO,SAAS,iBAAiB,QAA0C;AACzE,SAAO,OACJ,OAAO,CAAC,UAAU,MAAM,SAAS,WAAW,EAC5C,IAAI,CAAC,UAAU;AACd,UAAM,aAAa,MAAM;AACzB,WAAO,aACH,SAAS,WAAW,gBAAgB,GAAa,IAAI,IACrD;AAAA,EACN,CAAC,EACA,GAAG,CAAC;AACT;AAEO,SAAS,oBAAoB,QAA0C;AAC5E,SAAO,OACJ,OAAO,CAAC,UAAU,MAAM,SAAS,WAAW,EAC5C,IAAI,CAAC,UAAU;AACd,UAAM,aAAa,MAAM;AACzB,WAAO,aACH,SAAS,WAAW,mBAAmB,GAAa,IAAI,IACxD;AAAA,EACN,CAAC,EACA,GAAG,CAAC;AACT;AAEO,SAAS,kBAAkB,QAA0C;AAC1E,SAAO,OACJ,OAAO,CAAC,UAAU,MAAM,SAAS,WAAW,EAC5C,IAAI,CAAC,UAAU;AACd,UAAM,aAAa,MAAM;AACzB,WAAO,aACH,SAAS,WAAW,sBAAsB,GAAa,KAAM,IAC7D;AAAA,EACN,CAAC,EACA,GAAG,CAAC;AACT;AAEO,SAAS,0BACd,MACA,WACA;AACA,QAAM,cAAc,KAAK,YAAY;AACrC,QAAM,YAAY,CAAC,EAAE,YAAY,aAAa,WAAW;AACzD,SAAO;AAAA,IACL,iCAAiC,YAAY;AAAA,IAC7C,gCAAgC,YAAY,SAAS,WAAW,YAAY,OAAO;AAAA,IACnF,wCAAwC,YAAY,MAAM;AAAA,EAC5D;AACF;AAEO,SAAS,cACd,KAIA;AACA,SAAO,IAAI,SAAS;AACtB;AAEO,SAAS,cACd,KAIA;AACA,SACE,cAAc,GAAG,KACjB,IAAI,eAAe,KAAK,CAAC,YAAY;AACnC,WAAO,SAAS,UAAU,eAAe;AAAA,EAC3C,CAAC;AAEL;AAEO,SAAS,cACd,KAIA;AAEA,SAAO,cAAc,GAAG;AAC1B;AAEO,SAAS,cACd,KAIA;AAEA,SAAO,cAAc,GAAG;AAC1B;AAEA,eAAsB,yBAAyB,MAAc;AAC3D,QAAM,YAAY,MAAM,wBAAwB;AAChD,SAAO,iBAAiB,IAAI;AAAA;AAAA,yCAA0J,UAAU,aAAa,eAAe;AAAA,8BAAoC,UAAU,uBAAuB,iBAAiB;AAAA,aAAmB,IAAI;AAC3U;AAEA,eAAsB,wBAAwB;AAC5C,SAAO,yBAAyB,yBAAyB;AAC3D;AAEA,eAAsB,wBAAwB;AAC5C,SAAO,yBAAyB,wBAAwB;AAC1D;AAEA,eAAsB,wBAAwB;AAC5C,SAAO,yBAAyB,+BAA+B;AACjE;","names":[]}