inngest 4.7.0 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/components/DeferredFunction.cjs +52 -0
  3. package/components/DeferredFunction.cjs.map +1 -1
  4. package/components/DeferredFunction.d.cts +35 -9
  5. package/components/DeferredFunction.d.cts.map +1 -1
  6. package/components/DeferredFunction.d.ts +35 -9
  7. package/components/DeferredFunction.d.ts.map +1 -1
  8. package/components/DeferredFunction.js +53 -1
  9. package/components/DeferredFunction.js.map +1 -1
  10. package/components/Inngest.cjs +24 -1
  11. package/components/Inngest.cjs.map +1 -1
  12. package/components/Inngest.d.cts +23 -3
  13. package/components/Inngest.d.cts.map +1 -1
  14. package/components/Inngest.d.ts +23 -3
  15. package/components/Inngest.d.ts.map +1 -1
  16. package/components/Inngest.js +24 -1
  17. package/components/Inngest.js.map +1 -1
  18. package/components/InngestCommHandler.d.cts +2 -2
  19. package/components/InngestCommHandler.d.ts +2 -2
  20. package/components/InngestFunction.d.cts +2 -2
  21. package/components/InngestFunction.d.ts +2 -2
  22. package/components/InngestGroupTools.cjs +7 -4
  23. package/components/InngestGroupTools.cjs.map +1 -1
  24. package/components/InngestGroupTools.d.cts +5 -24
  25. package/components/InngestGroupTools.d.cts.map +1 -1
  26. package/components/InngestGroupTools.d.ts +5 -24
  27. package/components/InngestGroupTools.d.ts.map +1 -1
  28. package/components/InngestGroupTools.js +7 -4
  29. package/components/InngestGroupTools.js.map +1 -1
  30. package/components/InngestMetadata.cjs +18 -4
  31. package/components/InngestMetadata.cjs.map +1 -1
  32. package/components/InngestMetadata.d.cts +2 -2
  33. package/components/InngestMetadata.d.cts.map +1 -1
  34. package/components/InngestMetadata.d.ts +2 -2
  35. package/components/InngestMetadata.d.ts.map +1 -1
  36. package/components/InngestMetadata.js +18 -5
  37. package/components/InngestMetadata.js.map +1 -1
  38. package/components/InngestScore.cjs +93 -0
  39. package/components/InngestScore.cjs.map +1 -0
  40. package/components/InngestScore.d.cts +89 -0
  41. package/components/InngestScore.d.cts.map +1 -0
  42. package/components/InngestScore.d.ts +89 -0
  43. package/components/InngestScore.d.ts.map +1 -0
  44. package/components/InngestScore.js +88 -0
  45. package/components/InngestScore.js.map +1 -0
  46. package/components/InngestStepTools.cjs +9 -0
  47. package/components/InngestStepTools.cjs.map +1 -1
  48. package/components/InngestStepTools.d.cts +5 -3
  49. package/components/InngestStepTools.d.cts.map +1 -1
  50. package/components/InngestStepTools.d.ts +5 -3
  51. package/components/InngestStepTools.d.ts.map +1 -1
  52. package/components/InngestStepTools.js +9 -0
  53. package/components/InngestStepTools.js.map +1 -1
  54. package/components/ScoreFunction.cjs +37 -0
  55. package/components/ScoreFunction.cjs.map +1 -0
  56. package/components/ScoreFunction.d.cts +24 -0
  57. package/components/ScoreFunction.d.cts.map +1 -0
  58. package/components/ScoreFunction.d.ts +24 -0
  59. package/components/ScoreFunction.d.ts.map +1 -0
  60. package/components/ScoreFunction.js +37 -0
  61. package/components/ScoreFunction.js.map +1 -0
  62. package/components/execution/InngestExecution.d.cts +2 -2
  63. package/components/execution/InngestExecution.d.ts +2 -2
  64. package/components/execution/als.cjs.map +1 -1
  65. package/components/execution/als.d.cts +1 -0
  66. package/components/execution/als.d.cts.map +1 -1
  67. package/components/execution/als.d.ts +1 -0
  68. package/components/execution/als.d.ts.map +1 -1
  69. package/components/execution/als.js.map +1 -1
  70. package/components/execution/engine.cjs +12 -10
  71. package/components/execution/engine.cjs.map +1 -1
  72. package/components/execution/engine.d.cts +1 -1
  73. package/components/execution/engine.d.cts.map +1 -1
  74. package/components/execution/engine.d.ts +1 -1
  75. package/components/execution/engine.d.ts.map +1 -1
  76. package/components/execution/engine.js +13 -11
  77. package/components/execution/engine.js.map +1 -1
  78. package/components/execution/otel/aiExtractor.cjs +90 -125
  79. package/components/execution/otel/aiExtractor.cjs.map +1 -1
  80. package/components/execution/otel/aiExtractor.d.cts +48 -5
  81. package/components/execution/otel/aiExtractor.d.cts.map +1 -1
  82. package/components/execution/otel/aiExtractor.d.ts +48 -5
  83. package/components/execution/otel/aiExtractor.d.ts.map +1 -1
  84. package/components/execution/otel/aiExtractor.js +90 -125
  85. package/components/execution/otel/aiExtractor.js.map +1 -1
  86. package/components/execution/otel/middleware.cjs +3 -1
  87. package/components/execution/otel/middleware.cjs.map +1 -1
  88. package/components/execution/otel/middleware.d.cts +19 -12
  89. package/components/execution/otel/middleware.d.cts.map +1 -1
  90. package/components/execution/otel/middleware.d.ts +19 -12
  91. package/components/execution/otel/middleware.d.ts.map +1 -1
  92. package/components/execution/otel/middleware.js +4 -2
  93. package/components/execution/otel/middleware.js.map +1 -1
  94. package/components/execution/otel/util.cjs +9 -1
  95. package/components/execution/otel/util.cjs.map +1 -1
  96. package/components/execution/otel/util.js +9 -2
  97. package/components/execution/otel/util.js.map +1 -1
  98. package/components/realtime/types.d.cts +3 -3
  99. package/components/realtime/types.d.cts.map +1 -1
  100. package/components/realtime/types.d.ts +3 -3
  101. package/components/realtime/types.d.ts.map +1 -1
  102. package/experimental.cjs +5 -1
  103. package/experimental.d.cts +4 -1
  104. package/experimental.d.ts +4 -1
  105. package/experimental.js +3 -1
  106. package/helpers/consts.cjs +7 -0
  107. package/helpers/consts.cjs.map +1 -1
  108. package/helpers/consts.d.cts.map +1 -1
  109. package/helpers/consts.d.ts.map +1 -1
  110. package/helpers/consts.js +7 -1
  111. package/helpers/consts.js.map +1 -1
  112. package/helpers/errors.cjs +16 -0
  113. package/helpers/errors.cjs.map +1 -1
  114. package/helpers/errors.d.cts +12 -1
  115. package/helpers/errors.d.cts.map +1 -1
  116. package/helpers/errors.d.ts +12 -1
  117. package/helpers/errors.d.ts.map +1 -1
  118. package/helpers/errors.js +16 -1
  119. package/helpers/errors.js.map +1 -1
  120. package/helpers/types.cjs +4 -0
  121. package/helpers/types.cjs.map +1 -1
  122. package/helpers/types.js +4 -1
  123. package/helpers/types.js.map +1 -1
  124. package/index.d.cts +2 -2
  125. package/index.d.ts +2 -2
  126. package/package.json +1 -1
  127. package/types.cjs.map +1 -1
  128. package/types.d.cts +30 -9
  129. package/types.d.cts.map +1 -1
  130. package/types.d.ts +30 -9
  131. package/types.d.ts.map +1 -1
  132. package/types.js.map +1 -1
  133. package/version.cjs +1 -1
  134. package/version.cjs.map +1 -1
  135. package/version.d.cts +1 -1
  136. package/version.d.ts +1 -1
  137. package/version.js +1 -1
  138. package/version.js.map +1 -1
@@ -1,154 +1,119 @@
1
1
  //#region src/components/execution/otel/aiExtractor.ts
2
+ function textField(field, source) {
3
+ return {
4
+ field,
5
+ source,
6
+ valueType: "text",
7
+ merge: "replace"
8
+ };
9
+ }
10
+ function numberField(field, source, merge) {
11
+ return {
12
+ field,
13
+ source,
14
+ valueType: "number",
15
+ merge
16
+ };
17
+ }
2
18
  /**
3
- * A `convention` identifies a namespace of AI span attributes and orders which
4
- * should win when multiple namespaces are present on the same span. Lower
5
- * numbers override higher numbers.
6
- */
7
- var Convention = /* @__PURE__ */ function(Convention$1) {
8
- Convention$1[Convention$1["Langfuse"] = 1] = "Langfuse";
9
- Convention$1[Convention$1["Semconv"] = 2] = "Semconv";
10
- Convention$1[Convention$1["OpenInference"] = 3] = "OpenInference";
11
- Convention$1[Convention$1["Vercel"] = 4] = "Vercel";
12
- return Convention$1;
13
- }(Convention || {});
14
- /**
15
- * Prefix for the synthetic attributes produced by
16
- * {@link expandLangfuseUsageDetails}, kept distinct from any real attribute
17
- * namespace.
18
- */
19
- const langfuseUsagePrefix = "__langfuse.usage_details.";
20
- /**
21
- * Parses the `langfuse.observation.usage_details` JSON blob (e.g.
22
- * `{"input":17,"output":36,"total":53}`) and emits a synthetic scalar
23
- * attribute for each count we track. Only `input` is emitted; the other counts
24
- * (output, total, cached, reasoning, …) are intentionally dropped since this
25
- * extractor tracks input tokens alone.
26
- */
27
- const expandLangfuseUsageDetails = (value) => {
28
- if (typeof value !== "string" || value === "") return {};
29
- let counts;
30
- try {
31
- counts = JSON.parse(value);
32
- } catch {
33
- return {};
34
- }
35
- if (typeof counts !== "object" || counts === null) return {};
36
- const input = counts.input;
37
- if (typeof input !== "number") return {};
38
- return { [`${langfuseUsagePrefix}input`]: input };
39
- };
40
- /**
41
- * Maps a source attribute key to the canonical {@link AIMetadata} field it
42
- * populates and the convention it belongs to.
19
+ * Every `gen_ai.*` attribute we capture, mapped to its canonical field.
20
+ *
21
+ * Anything not listed here (prompt/response content, messages, tool calls,
22
+ * unknown keys) is ignored.
43
23
  */
44
- const keyFieldMap = {
45
- "langfuse.observation.usage_details": {
46
- convention: Convention.Langfuse,
47
- expand: expandLangfuseUsageDetails
48
- },
49
- [`${langfuseUsagePrefix}input`]: {
50
- field: "inputTokens",
51
- convention: Convention.Langfuse
52
- },
53
- "gen_ai.request.model": {
54
- field: "model",
55
- convention: Convention.Semconv
56
- },
57
- "gen_ai.usage.input_tokens": {
58
- field: "inputTokens",
59
- convention: Convention.Semconv
60
- },
61
- "llm.model_name": {
62
- field: "model",
63
- convention: Convention.OpenInference
64
- },
65
- "llm.token_count.prompt": {
66
- field: "inputTokens",
67
- convention: Convention.OpenInference
68
- },
69
- "ai.model.id": {
70
- field: "model",
71
- convention: Convention.Vercel
72
- },
73
- "ai.usage.inputTokens": {
74
- field: "inputTokens",
75
- convention: Convention.Vercel
76
- },
77
- "ai.usage.tokens": {
78
- field: "inputTokens",
79
- convention: Convention.Vercel
80
- }
81
- };
24
+ const FIELD_SPECS = [
25
+ textField("requestModel", "gen_ai.request.model"),
26
+ textField("responseModel", "gen_ai.response.model"),
27
+ textField("provider", "gen_ai.provider.name"),
28
+ textField("responseId", "gen_ai.response.id"),
29
+ numberField("inputTokens", "gen_ai.usage.input_tokens", "sum"),
30
+ numberField("outputTokens", "gen_ai.usage.output_tokens", "sum"),
31
+ numberField("totalTokens", "gen_ai.usage.total_tokens", "sum"),
32
+ numberField("cacheReadTokens", "gen_ai.usage.cache_read.input_tokens", "sum"),
33
+ numberField("cacheCreationTokens", "gen_ai.usage.cache_creation.input_tokens", "sum"),
34
+ numberField("reasoningTokens", "gen_ai.usage.reasoning.output_tokens", "sum"),
35
+ numberField("temperature", "gen_ai.request.temperature", "replace"),
36
+ numberField("topP", "gen_ai.request.top_p", "replace"),
37
+ numberField("maxTokens", "gen_ai.request.max_tokens", "replace"),
38
+ numberField("frequencyPenalty", "gen_ai.request.frequency_penalty", "replace"),
39
+ numberField("presencePenalty", "gen_ai.request.presence_penalty", "replace"),
40
+ numberField("seed", "gen_ai.request.seed", "replace")
41
+ ];
42
+ function parseNumericAttribute(value) {
43
+ if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
44
+ if (typeof value !== "string" || value === "") return;
45
+ const num = Number(value);
46
+ return Number.isFinite(num) ? num : void 0;
47
+ }
82
48
  /**
83
- * Extracts AI model metadata from a span's attributes.
49
+ * Extracts {@link AIMetadata} from a span's attributes.
50
+ *
51
+ * Only the allowlisted {@link FIELD_SPECS} are read. Every other attribute is
52
+ * ignored. Numeric fields accept numbers and quoted numeric strings and are
53
+ * otherwise dropped, as OTLP/JSON may encode int64 as a quoted string. Text
54
+ * fields are dropped when empty.
84
55
  *
85
- * Attributes are matched across multiple instrumentation conventions
86
- * (OpenTelemetry semconv, OpenInference, Vercel AI SDK). When more than one
87
- * convention supplies the same field, the highest-precedence value wins.
56
+ * Returns an empty object for spans carrying no recognised `gen_ai.*`
57
+ * attributes.
88
58
  *
89
59
  * @param attributes - The span attributes, as exposed by
90
60
  * `ReadableSpan.attributes`.
91
61
  */
92
62
  const extractAIMetadataFromAttributes = (attributes) => {
93
- const candidates = {};
94
- const record = (mapping, value) => {
95
- if (!mapping.field) return;
96
- const existing = candidates[mapping.field];
97
- if (!existing || mapping.convention < existing.convention) candidates[mapping.field] = {
98
- value,
99
- convention: mapping.convention
100
- };
101
- };
102
- for (const [key, value] of Object.entries(attributes)) {
63
+ const metadata = {};
64
+ for (const spec of FIELD_SPECS) {
65
+ const value = attributes[spec.source];
103
66
  if (value === void 0) continue;
104
- const mapping = keyFieldMap[key];
105
- if (!mapping) continue;
106
- if (mapping.expand) {
107
- for (const [childKey, childValue] of Object.entries(mapping.expand(value))) {
108
- const childMapping = keyFieldMap[childKey];
109
- if (childMapping) record(childMapping, childValue);
110
- }
111
- continue;
67
+ if (spec.valueType === "text") {
68
+ const text = typeof value === "string" ? value : String(value);
69
+ if (text !== "") metadata[spec.field] = text;
70
+ } else {
71
+ const num = parseNumericAttribute(value);
72
+ if (num !== void 0) metadata[spec.field] = num;
112
73
  }
113
- record(mapping, value);
114
- }
115
- const metadata = {};
116
- const model = candidates.model?.value;
117
- if (typeof model === "string" && model !== "") metadata.model = model;
118
- const inputTokens = candidates.inputTokens?.value;
119
- if (inputTokens !== void 0) {
120
- const n = Number(inputTokens);
121
- if (!Number.isNaN(n)) metadata.inputTokens = n;
122
74
  }
123
75
  return metadata;
124
76
  };
125
77
  /**
126
- * Aggregates two {@link AIMetadata} values into one.
78
+ * Aggregates two {@link AIMetadata} values, folding a later call's metadata into
79
+ * an earlier accumulator for a single step.
80
+ *
81
+ * - Token-count fields (`merge: "sum"`) are **summed**, so a step that makes
82
+ * several LLM calls reports their combined usage.
83
+ * - Every other field uses `merge: "replace"` (`b` overwrites `a`)
127
84
  *
128
- * Input token counts are summed, while `a`'s model takes precedence over `b`'s.
129
- * Each field is only present in the result when at least one input supplies it.
85
+ * A field is present in the result only when at least one input supplies it.
130
86
  *
131
- * @param a - The primary metadata; its `model` wins when both are present.
132
- * @param b - The secondary metadata.
87
+ * @param a - The accumulator (earlier calls).
88
+ * @param b - The later metadata, whose values win on conflict (and add for sums).
133
89
  */
134
90
  const aggregate = (a, b) => {
135
- const metadata = {};
136
- const model = a.model ?? b.model;
137
- if (model !== void 0) metadata.model = model;
138
- if (a.inputTokens !== void 0 || b.inputTokens !== void 0) metadata.inputTokens = (a.inputTokens ?? 0) + (b.inputTokens ?? 0);
139
- return metadata;
91
+ const out = { ...a };
92
+ for (const spec of FIELD_SPECS) if (spec.valueType === "number") {
93
+ const bValue = b[spec.field];
94
+ if (bValue === void 0) continue;
95
+ if (spec.merge === "sum") out[spec.field] = (out[spec.field] ?? 0) + bValue;
96
+ else out[spec.field] = bValue;
97
+ } else if (spec.valueType === "text") {
98
+ const bValue = b[spec.field];
99
+ if (bValue === void 0) continue;
100
+ out[spec.field] = bValue;
101
+ }
102
+ return out;
140
103
  };
104
+ /** Converts a canonical camelCase field name to the server's snake_case key. */
105
+ const toSnakeCase = (field) => field.replace(/[A-Z]/g, (char) => `_${char.toLowerCase()}`);
141
106
  /**
142
107
  * Maps an {@link AIMetadata} value onto the server's `inngest.ai` metadata
143
- * schema (snake_case keys). Only the fields we extract are emitted; absent
144
- * fields are omitted rather than zero-valued. Returns `undefined` when there
145
- * is nothing to emit, so callers can skip stamping metadata entirely.
108
+ * values, converting each canonical camelCase field to snake_case (e.g.
109
+ * `inputTokens` `input_tokens`). Returns `undefined` when there is nothing to
110
+ * emit so callers can skip stamping metadata entirely.
146
111
  */
147
112
  const toInngestAIMetadataValues = (metadata) => {
113
+ const entries = Object.entries(metadata);
114
+ if (entries.length === 0) return;
148
115
  const values = {};
149
- if (metadata.model !== void 0) values.model = metadata.model;
150
- if (metadata.inputTokens !== void 0) values.input_tokens = metadata.inputTokens;
151
- if (Object.keys(values).length === 0) return;
116
+ for (const [field, value] of entries) values[toSnakeCase(field)] = value;
152
117
  return values;
153
118
  };
154
119
 
@@ -1 +1 @@
1
- {"version":3,"file":"aiExtractor.js","names":["counts: unknown","keyFieldMap: Record<string, Mapping>","candidates: Partial<Record<Field, Candidate>>","metadata: AIMetadata","values: Record<string, unknown>"],"sources":["../../../../src/components/execution/otel/aiExtractor.ts"],"sourcesContent":["import type { Attributes, AttributeValue } from \"@opentelemetry/api\";\n\n/**\n * AI metadata extracted from a span's attributes.\n *\n * A field is only present when a matching attribute was found on the span;\n * absent fields are omitted rather than zero-valued.\n */\nexport interface AIMetadata {\n /** The requested model, e.g. `gpt-4.1-nano`. */\n model?: string;\n /** The number of input (prompt) tokens consumed by the request. */\n inputTokens?: number;\n}\n\n/**\n * A `convention` identifies a namespace of AI span attributes and orders which\n * should win when multiple namespaces are present on the same span. Lower\n * numbers override higher numbers.\n */\nenum Convention {\n Langfuse = 1,\n Semconv = 2,\n OpenInference = 3,\n Vercel = 4,\n}\n\ntype Field = keyof AIMetadata;\n\ninterface Mapping {\n /**\n * The canonical {@link AIMetadata} field this attribute populates. Omitted\n * for composite attributes that only carry an {@link Mapping.expand}.\n */\n field?: Field;\n convention: Convention;\n /**\n * Composite attributes (e.g. a JSON blob of token counts) provide an\n * `expand` that explodes the raw value into synthetic scalar attributes,\n * each re-matched against {@link keyFieldMap}.\n */\n expand?: (value: AttributeValue) => Record<string, AttributeValue>;\n}\n\n/**\n * Prefix for the synthetic attributes produced by\n * {@link expandLangfuseUsageDetails}, kept distinct from any real attribute\n * namespace.\n */\nconst langfuseUsagePrefix = \"__langfuse.usage_details.\";\n\n/**\n * Parses the `langfuse.observation.usage_details` JSON blob (e.g.\n * `{\"input\":17,\"output\":36,\"total\":53}`) and emits a synthetic scalar\n * attribute for each count we track. Only `input` is emitted; the other counts\n * (output, total, cached, reasoning, …) are intentionally dropped since this\n * extractor tracks input tokens alone.\n */\nconst expandLangfuseUsageDetails = (\n value: AttributeValue,\n): Record<string, AttributeValue> => {\n if (typeof value !== \"string\" || value === \"\") {\n return {};\n }\n\n let counts: unknown;\n try {\n counts = JSON.parse(value);\n } catch {\n return {};\n }\n\n if (typeof counts !== \"object\" || counts === null) {\n return {};\n }\n\n const input = (counts as Record<string, unknown>).input;\n if (typeof input !== \"number\") {\n return {};\n }\n\n return { [`${langfuseUsagePrefix}input`]: input };\n};\n\n/**\n * Maps a source attribute key to the canonical {@link AIMetadata} field it\n * populates and the convention it belongs to.\n */\nconst keyFieldMap: Record<string, Mapping> = {\n // Langfuse (`langfuse.*` telemetry). Langfuse reports token usage as a single\n // JSON blob under `usage_details`; it is expanded into synthetic per-count\n // attributes that are matched back through this map. Langfuse only emits a\n // response model (not the requested model), which this extractor doesn't\n // track, so no `model` mapping is registered here. Langfuse outranks the\n // other conventions when several are present on one span.\n \"langfuse.observation.usage_details\": {\n convention: Convention.Langfuse,\n expand: expandLangfuseUsageDetails,\n },\n [`${langfuseUsagePrefix}input`]: {\n field: \"inputTokens\",\n convention: Convention.Langfuse,\n },\n\n // OpenTelemetry Semantic Conventions\n \"gen_ai.request.model\": { field: \"model\", convention: Convention.Semconv },\n \"gen_ai.usage.input_tokens\": {\n field: \"inputTokens\",\n convention: Convention.Semconv,\n },\n\n // OpenInference\n \"llm.model_name\": { field: \"model\", convention: Convention.OpenInference },\n \"llm.token_count.prompt\": {\n field: \"inputTokens\",\n convention: Convention.OpenInference,\n },\n\n // Vercel AI SDK (native `ai.*` telemetry)\n \"ai.model.id\": { field: \"model\", convention: Convention.Vercel },\n \"ai.usage.inputTokens\": {\n field: \"inputTokens\",\n convention: Convention.Vercel,\n },\n // Embeddings spans emit only a single `ai.usage.tokens` count (no\n // input/output split); map it to inputTokens to match the semconv embeddings\n // case.\n \"ai.usage.tokens\": { field: \"inputTokens\", convention: Convention.Vercel },\n};\n\ninterface Candidate {\n value: AttributeValue;\n convention: Convention;\n}\n\n/**\n * Extracts AI model metadata from a span's attributes.\n *\n * Attributes are matched across multiple instrumentation conventions\n * (OpenTelemetry semconv, OpenInference, Vercel AI SDK). When more than one\n * convention supplies the same field, the highest-precedence value wins.\n *\n * @param attributes - The span attributes, as exposed by\n * `ReadableSpan.attributes`.\n */\nexport const extractAIMetadataFromAttributes = (\n attributes: Attributes,\n): AIMetadata => {\n // Track the highest-precedence (lowest convention) candidate seen per field.\n const candidates: Partial<Record<Field, Candidate>> = {};\n\n const record = (mapping: Mapping, value: AttributeValue) => {\n if (!mapping.field) {\n return;\n }\n const existing = candidates[mapping.field];\n if (!existing || mapping.convention < existing.convention) {\n candidates[mapping.field] = { value, convention: mapping.convention };\n }\n };\n\n for (const [key, value] of Object.entries(attributes)) {\n if (value === undefined) {\n continue;\n }\n\n const mapping = keyFieldMap[key];\n if (!mapping) {\n continue;\n }\n\n // Composite attribute: explode into synthetic children and match each back\n // through the map.\n if (mapping.expand) {\n for (const [childKey, childValue] of Object.entries(\n mapping.expand(value),\n )) {\n const childMapping = keyFieldMap[childKey];\n if (childMapping) {\n record(childMapping, childValue);\n }\n }\n continue;\n }\n\n record(mapping, value);\n }\n\n const metadata: AIMetadata = {};\n\n const model = candidates.model?.value;\n if (typeof model === \"string\" && model !== \"\") {\n metadata.model = model;\n }\n\n const inputTokens = candidates.inputTokens?.value;\n if (inputTokens !== undefined) {\n // Token counts arrive as numbers from the SDK, but OTLP/JSON encodes int64\n // as either a number or a quoted string, so coerce defensively.\n const n = Number(inputTokens);\n if (!Number.isNaN(n)) {\n metadata.inputTokens = n;\n }\n }\n\n return metadata;\n};\n\n/**\n * Aggregates two {@link AIMetadata} values into one.\n *\n * Input token counts are summed, while `a`'s model takes precedence over `b`'s.\n * Each field is only present in the result when at least one input supplies it.\n *\n * @param a - The primary metadata; its `model` wins when both are present.\n * @param b - The secondary metadata.\n */\nexport const aggregate = (a: AIMetadata, b: AIMetadata): AIMetadata => {\n const metadata: AIMetadata = {};\n\n const model = a.model ?? b.model;\n if (model !== undefined) {\n metadata.model = model;\n }\n\n if (a.inputTokens !== undefined || b.inputTokens !== undefined) {\n metadata.inputTokens = (a.inputTokens ?? 0) + (b.inputTokens ?? 0);\n }\n\n return metadata;\n};\n\n/**\n * Maps an {@link AIMetadata} value onto the server's `inngest.ai` metadata\n * schema (snake_case keys). Only the fields we extract are emitted; absent\n * fields are omitted rather than zero-valued. Returns `undefined` when there\n * is nothing to emit, so callers can skip stamping metadata entirely.\n */\nexport const toInngestAIMetadataValues = (\n metadata: AIMetadata,\n): Record<string, unknown> | undefined => {\n const values: Record<string, unknown> = {};\n\n if (metadata.model !== undefined) {\n values.model = metadata.model;\n }\n\n if (metadata.inputTokens !== undefined) {\n values.input_tokens = metadata.inputTokens;\n }\n\n if (Object.keys(values).length === 0) {\n return undefined;\n }\n\n return values;\n};\n"],"mappings":";;;;;;AAoBA,IAAK,oDAAL;AACE;AACA;AACA;AACA;;EAJG;;;;;;AA6BL,MAAM,sBAAsB;;;;;;;;AAS5B,MAAM,8BACJ,UACmC;AACnC,KAAI,OAAO,UAAU,YAAY,UAAU,GACzC,QAAO,EAAE;CAGX,IAAIA;AACJ,KAAI;AACF,WAAS,KAAK,MAAM,MAAM;SACpB;AACN,SAAO,EAAE;;AAGX,KAAI,OAAO,WAAW,YAAY,WAAW,KAC3C,QAAO,EAAE;CAGX,MAAM,QAAS,OAAmC;AAClD,KAAI,OAAO,UAAU,SACnB,QAAO,EAAE;AAGX,QAAO,GAAG,GAAG,oBAAoB,SAAS,OAAO;;;;;;AAOnD,MAAMC,cAAuC;CAO3C,sCAAsC;EACpC,YAAY,WAAW;EACvB,QAAQ;EACT;EACA,GAAG,oBAAoB,SAAS;EAC/B,OAAO;EACP,YAAY,WAAW;EACxB;CAGD,wBAAwB;EAAE,OAAO;EAAS,YAAY,WAAW;EAAS;CAC1E,6BAA6B;EAC3B,OAAO;EACP,YAAY,WAAW;EACxB;CAGD,kBAAkB;EAAE,OAAO;EAAS,YAAY,WAAW;EAAe;CAC1E,0BAA0B;EACxB,OAAO;EACP,YAAY,WAAW;EACxB;CAGD,eAAe;EAAE,OAAO;EAAS,YAAY,WAAW;EAAQ;CAChE,wBAAwB;EACtB,OAAO;EACP,YAAY,WAAW;EACxB;CAID,mBAAmB;EAAE,OAAO;EAAe,YAAY,WAAW;EAAQ;CAC3E;;;;;;;;;;;AAiBD,MAAa,mCACX,eACe;CAEf,MAAMC,aAAgD,EAAE;CAExD,MAAM,UAAU,SAAkB,UAA0B;AAC1D,MAAI,CAAC,QAAQ,MACX;EAEF,MAAM,WAAW,WAAW,QAAQ;AACpC,MAAI,CAAC,YAAY,QAAQ,aAAa,SAAS,WAC7C,YAAW,QAAQ,SAAS;GAAE;GAAO,YAAY,QAAQ;GAAY;;AAIzE,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,EAAE;AACrD,MAAI,UAAU,OACZ;EAGF,MAAM,UAAU,YAAY;AAC5B,MAAI,CAAC,QACH;AAKF,MAAI,QAAQ,QAAQ;AAClB,QAAK,MAAM,CAAC,UAAU,eAAe,OAAO,QAC1C,QAAQ,OAAO,MAAM,CACtB,EAAE;IACD,MAAM,eAAe,YAAY;AACjC,QAAI,aACF,QAAO,cAAc,WAAW;;AAGpC;;AAGF,SAAO,SAAS,MAAM;;CAGxB,MAAMC,WAAuB,EAAE;CAE/B,MAAM,QAAQ,WAAW,OAAO;AAChC,KAAI,OAAO,UAAU,YAAY,UAAU,GACzC,UAAS,QAAQ;CAGnB,MAAM,cAAc,WAAW,aAAa;AAC5C,KAAI,gBAAgB,QAAW;EAG7B,MAAM,IAAI,OAAO,YAAY;AAC7B,MAAI,CAAC,OAAO,MAAM,EAAE,CAClB,UAAS,cAAc;;AAI3B,QAAO;;;;;;;;;;;AAYT,MAAa,aAAa,GAAe,MAA8B;CACrE,MAAMA,WAAuB,EAAE;CAE/B,MAAM,QAAQ,EAAE,SAAS,EAAE;AAC3B,KAAI,UAAU,OACZ,UAAS,QAAQ;AAGnB,KAAI,EAAE,gBAAgB,UAAa,EAAE,gBAAgB,OACnD,UAAS,eAAe,EAAE,eAAe,MAAM,EAAE,eAAe;AAGlE,QAAO;;;;;;;;AAST,MAAa,6BACX,aACwC;CACxC,MAAMC,SAAkC,EAAE;AAE1C,KAAI,SAAS,UAAU,OACrB,QAAO,QAAQ,SAAS;AAG1B,KAAI,SAAS,gBAAgB,OAC3B,QAAO,eAAe,SAAS;AAGjC,KAAI,OAAO,KAAK,OAAO,CAAC,WAAW,EACjC;AAGF,QAAO"}
1
+ {"version":3,"file":"aiExtractor.js","names":["metadata: AIMetadata","out: AIMetadata","values: Record<string, unknown>"],"sources":["../../../../src/components/execution/otel/aiExtractor.ts"],"sourcesContent":["import type { Attributes } from \"@opentelemetry/api\";\n\n/**\n * Canonical AI metadata extracted from a span's OpenTelemetry GenAI semantic\n * convention (`gen_ai.*`) attributes.\n *\n * The fields below are an explicit **allowlist**: only these are ever read from\n * a span (see {@link FIELD_SPECS}). Anything not mapped — prompt/response\n * content, messages, tool calls, embeddings payloads, and other\n * potentially-sensitive or bulky attributes — is not captured.\n *\n * For each category we describe how multiple AIMetadata values are aggregated\n * (see {@link aggregate}).\n */\nexport interface AIMetadata {\n // Identity & classification (last-write-wins).\n\n /** The requested model, e.g. `gpt-4.1-nano`. */\n requestModel?: string;\n /**\n * The model that actually served the request. This is often a dated snapshot\n * of the requested {@link AIMetadata.requestModel} (e.g.\n * `gpt-4.1-nano-2025-04-14`).\n */\n responseModel?: string;\n /** The AI provider that served the request (e.g. `openai`) */\n provider?: string;\n /** The provider's identifier for the response, e.g. `chatcmpl-...`. */\n responseId?: string;\n\n // Token usage (summed).\n\n /** The number of input tokens consumed by the request. */\n inputTokens?: number;\n /** The number of output tokens produced by the response. */\n outputTokens?: number;\n /** The total tokens consumed, as reported by the provider. */\n totalTokens?: number;\n /**\n * Cached input tokens read from the prompt cache. Providers differ on\n * accounting. OpenAI's cached tokens are a subset of\n * {@link AIMetadata.inputTokens}, Anthropic's are additive. Callers must\n * not assume a single relationship.\n */\n cacheReadTokens?: number;\n /** Tokens written to the prompt cache. */\n cacheCreationTokens?: number;\n /** Reasoning/thinking tokens, when the emitter reports them separately. */\n reasoningTokens?: number;\n\n // Request / inference parameters (last-write-wins). These describe the\n // request the caller made, not the response, and are stored raw as the\n // emitter reports them.\n\n /** Sampling temperature requested, e.g. `0.7`. */\n temperature?: number;\n /** Nucleus sampling probability mass requested (`top_p`), e.g. `0.9`. */\n topP?: number;\n /** Upper bound on tokens to generate (`max_tokens`). */\n maxTokens?: number;\n /** Frequency penalty requested. */\n frequencyPenalty?: number;\n /** Presence penalty requested. */\n presencePenalty?: number;\n /** Sampling seed requested, when the emitter reports it. */\n seed?: number;\n}\n\ntype ValueType = \"text\" | \"number\";\ntype MergeStrategy = \"replace\" | \"sum\";\n\n/**\n * Derives the subset of AIMetadata keys whose assigned value matches TValue.\n *\n * AIMetadata fields are optional (`model?: string`), so each field's type is\n * effectively `string | undefined` or `number | undefined`. `Exclude` removes\n * `undefined` before checking the value type, and `-?` prevents optional fields\n * from adding `undefined` back into the final key union.\n */\ntype FieldsWithValue<TValue> = {\n [TField in keyof AIMetadata]-?: Exclude<\n AIMetadata[TField],\n undefined\n > extends TValue\n ? TField\n : never;\n}[keyof AIMetadata];\n\ntype TextField = FieldsWithValue<string>;\ntype NumberField = FieldsWithValue<number>;\n\ninterface BaseFieldSpec {\n /** The source `gen_ai.*` attribute key. */\n source: string;\n valueType: ValueType;\n merge: MergeStrategy;\n}\n\ninterface TextFieldSpec extends BaseFieldSpec {\n /** The canonical {@link AIMetadata} field this populates. */\n field: TextField;\n valueType: \"text\";\n merge: \"replace\";\n}\n\ninterface NumberFieldSpec extends BaseFieldSpec {\n /** The canonical {@link AIMetadata} field this populates. */\n field: NumberField;\n valueType: \"number\";\n}\n\ntype FieldSpec = TextFieldSpec | NumberFieldSpec;\n\nfunction textField(field: TextField, source: string): TextFieldSpec {\n return {\n field,\n source,\n valueType: \"text\",\n merge: \"replace\",\n };\n}\n\nfunction numberField(\n field: NumberField,\n source: string,\n merge: MergeStrategy,\n): NumberFieldSpec {\n return {\n field,\n source,\n valueType: \"number\",\n merge,\n };\n}\n\n/**\n * Every `gen_ai.*` attribute we capture, mapped to its canonical field.\n *\n * Anything not listed here (prompt/response content, messages, tool calls,\n * unknown keys) is ignored.\n */\nexport const FIELD_SPECS = [\n // Identity & classification.\n textField(\"requestModel\", \"gen_ai.request.model\"),\n textField(\"responseModel\", \"gen_ai.response.model\"),\n textField(\"provider\", \"gen_ai.provider.name\"),\n textField(\"responseId\", \"gen_ai.response.id\"),\n\n // Token usage.\n numberField(\"inputTokens\", \"gen_ai.usage.input_tokens\", \"sum\"),\n numberField(\"outputTokens\", \"gen_ai.usage.output_tokens\", \"sum\"),\n numberField(\"totalTokens\", \"gen_ai.usage.total_tokens\", \"sum\"),\n numberField(\"cacheReadTokens\", \"gen_ai.usage.cache_read.input_tokens\", \"sum\"),\n numberField(\n \"cacheCreationTokens\",\n \"gen_ai.usage.cache_creation.input_tokens\",\n \"sum\",\n ),\n numberField(\"reasoningTokens\", \"gen_ai.usage.reasoning.output_tokens\", \"sum\"),\n\n // Request / inference parameters. These describe the request, not a quantity,\n // so they replace rather than sum when a step makes several calls.\n numberField(\"temperature\", \"gen_ai.request.temperature\", \"replace\"),\n numberField(\"topP\", \"gen_ai.request.top_p\", \"replace\"),\n numberField(\"maxTokens\", \"gen_ai.request.max_tokens\", \"replace\"),\n numberField(\n \"frequencyPenalty\",\n \"gen_ai.request.frequency_penalty\",\n \"replace\",\n ),\n numberField(\"presencePenalty\", \"gen_ai.request.presence_penalty\", \"replace\"),\n numberField(\"seed\", \"gen_ai.request.seed\", \"replace\"),\n] as const satisfies readonly FieldSpec[];\n\nfunction parseNumericAttribute(value: unknown): number | undefined {\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : undefined;\n }\n\n if (typeof value !== \"string\" || value === \"\") {\n return undefined;\n }\n\n const num = Number(value);\n return Number.isFinite(num) ? num : undefined;\n}\n\n/**\n * Extracts {@link AIMetadata} from a span's attributes.\n *\n * Only the allowlisted {@link FIELD_SPECS} are read. Every other attribute is\n * ignored. Numeric fields accept numbers and quoted numeric strings and are\n * otherwise dropped, as OTLP/JSON may encode int64 as a quoted string. Text\n * fields are dropped when empty.\n *\n * Returns an empty object for spans carrying no recognised `gen_ai.*`\n * attributes.\n *\n * @param attributes - The span attributes, as exposed by\n * `ReadableSpan.attributes`.\n */\nexport const extractAIMetadataFromAttributes = (\n attributes: Attributes,\n): AIMetadata => {\n const metadata: AIMetadata = {};\n\n for (const spec of FIELD_SPECS) {\n const value = attributes[spec.source];\n if (value === undefined) {\n continue;\n }\n\n if (spec.valueType === \"text\") {\n const text = typeof value === \"string\" ? value : String(value);\n if (text !== \"\") {\n metadata[spec.field] = text;\n }\n } else {\n const num = parseNumericAttribute(value);\n if (num !== undefined) {\n metadata[spec.field] = num;\n }\n }\n }\n\n return metadata;\n};\n\n/**\n * Aggregates two {@link AIMetadata} values, folding a later call's metadata into\n * an earlier accumulator for a single step.\n *\n * - Token-count fields (`merge: \"sum\"`) are **summed**, so a step that makes\n * several LLM calls reports their combined usage.\n * - Every other field uses `merge: \"replace\"` (`b` overwrites `a`)\n *\n * A field is present in the result only when at least one input supplies it.\n *\n * @param a - The accumulator (earlier calls).\n * @param b - The later metadata, whose values win on conflict (and add for sums).\n */\nexport const aggregate = (a: AIMetadata, b: AIMetadata): AIMetadata => {\n const out: AIMetadata = { ...a };\n\n for (const spec of FIELD_SPECS) {\n if (spec.valueType === \"number\") {\n const bValue = b[spec.field];\n if (bValue === undefined) {\n continue;\n }\n\n if (spec.merge === \"sum\") {\n out[spec.field] = (out[spec.field] ?? 0) + bValue;\n } else {\n out[spec.field] = bValue;\n }\n } else if (spec.valueType === \"text\") {\n // Text fields are always replace.\n const bValue = b[spec.field];\n if (bValue === undefined) {\n continue;\n }\n out[spec.field] = bValue;\n }\n }\n\n return out;\n};\n\n/** Converts a canonical camelCase field name to the server's snake_case key. */\nconst toSnakeCase = (field: string): string =>\n field.replace(/[A-Z]/g, (char) => `_${char.toLowerCase()}`);\n\n/**\n * Maps an {@link AIMetadata} value onto the server's `inngest.ai` metadata\n * values, converting each canonical camelCase field to snake_case (e.g.\n * `inputTokens` → `input_tokens`). Returns `undefined` when there is nothing to\n * emit so callers can skip stamping metadata entirely.\n */\nexport const toInngestAIMetadataValues = (\n metadata: AIMetadata,\n): Record<string, unknown> | undefined => {\n const entries = Object.entries(metadata);\n if (entries.length === 0) {\n return undefined;\n }\n\n const values: Record<string, unknown> = {};\n for (const [field, value] of entries) {\n values[toSnakeCase(field)] = value;\n }\n\n return values;\n};\n"],"mappings":";AAiHA,SAAS,UAAU,OAAkB,QAA+B;AAClE,QAAO;EACL;EACA;EACA,WAAW;EACX,OAAO;EACR;;AAGH,SAAS,YACP,OACA,QACA,OACiB;AACjB,QAAO;EACL;EACA;EACA,WAAW;EACX;EACD;;;;;;;;AASH,MAAa,cAAc;CAEzB,UAAU,gBAAgB,uBAAuB;CACjD,UAAU,iBAAiB,wBAAwB;CACnD,UAAU,YAAY,uBAAuB;CAC7C,UAAU,cAAc,qBAAqB;CAG7C,YAAY,eAAe,6BAA6B,MAAM;CAC9D,YAAY,gBAAgB,8BAA8B,MAAM;CAChE,YAAY,eAAe,6BAA6B,MAAM;CAC9D,YAAY,mBAAmB,wCAAwC,MAAM;CAC7E,YACE,uBACA,4CACA,MACD;CACD,YAAY,mBAAmB,wCAAwC,MAAM;CAI7E,YAAY,eAAe,8BAA8B,UAAU;CACnE,YAAY,QAAQ,wBAAwB,UAAU;CACtD,YAAY,aAAa,6BAA6B,UAAU;CAChE,YACE,oBACA,oCACA,UACD;CACD,YAAY,mBAAmB,mCAAmC,UAAU;CAC5E,YAAY,QAAQ,uBAAuB,UAAU;CACtD;AAED,SAAS,sBAAsB,OAAoC;AACjE,KAAI,OAAO,UAAU,SACnB,QAAO,OAAO,SAAS,MAAM,GAAG,QAAQ;AAG1C,KAAI,OAAO,UAAU,YAAY,UAAU,GACzC;CAGF,MAAM,MAAM,OAAO,MAAM;AACzB,QAAO,OAAO,SAAS,IAAI,GAAG,MAAM;;;;;;;;;;;;;;;;AAiBtC,MAAa,mCACX,eACe;CACf,MAAMA,WAAuB,EAAE;AAE/B,MAAK,MAAM,QAAQ,aAAa;EAC9B,MAAM,QAAQ,WAAW,KAAK;AAC9B,MAAI,UAAU,OACZ;AAGF,MAAI,KAAK,cAAc,QAAQ;GAC7B,MAAM,OAAO,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM;AAC9D,OAAI,SAAS,GACX,UAAS,KAAK,SAAS;SAEpB;GACL,MAAM,MAAM,sBAAsB,MAAM;AACxC,OAAI,QAAQ,OACV,UAAS,KAAK,SAAS;;;AAK7B,QAAO;;;;;;;;;;;;;;;AAgBT,MAAa,aAAa,GAAe,MAA8B;CACrE,MAAMC,MAAkB,EAAE,GAAG,GAAG;AAEhC,MAAK,MAAM,QAAQ,YACjB,KAAI,KAAK,cAAc,UAAU;EAC/B,MAAM,SAAS,EAAE,KAAK;AACtB,MAAI,WAAW,OACb;AAGF,MAAI,KAAK,UAAU,MACjB,KAAI,KAAK,UAAU,IAAI,KAAK,UAAU,KAAK;MAE3C,KAAI,KAAK,SAAS;YAEX,KAAK,cAAc,QAAQ;EAEpC,MAAM,SAAS,EAAE,KAAK;AACtB,MAAI,WAAW,OACb;AAEF,MAAI,KAAK,SAAS;;AAItB,QAAO;;;AAIT,MAAM,eAAe,UACnB,MAAM,QAAQ,WAAW,SAAS,IAAI,KAAK,aAAa,GAAG;;;;;;;AAQ7D,MAAa,6BACX,aACwC;CACxC,MAAM,UAAU,OAAO,QAAQ,SAAS;AACxC,KAAI,QAAQ,WAAW,EACrB;CAGF,MAAMC,SAAkC,EAAE;AAC1C,MAAK,MAAM,CAAC,OAAO,UAAU,QAC3B,QAAO,YAAY,MAAM,IAAI;AAG/B,QAAO"}
@@ -37,6 +37,7 @@ const extendedTracesMiddleware = ({ behaviour = "auto", instrumentations, logLev
37
37
  processor = extended.processor;
38
38
  break;
39
39
  }
40
+ require_util.warnDeprecatedCreateProviderBehaviour(behaviour);
40
41
  processorReady = require_util.createProvider(behaviour, instrumentations).then((created) => {
41
42
  if (created.success) {
42
43
  devDebug("created new provider");
@@ -46,6 +47,7 @@ const extendedTracesMiddleware = ({ behaviour = "auto", instrumentations, logLev
46
47
  break;
47
48
  }
48
49
  case "createProvider":
50
+ require_util.warnDeprecatedCreateProviderBehaviour(behaviour);
49
51
  processorReady = require_util.createProvider(behaviour, instrumentations).then((created) => {
50
52
  if (created.success) {
51
53
  devDebug("created new provider");
@@ -60,7 +62,7 @@ const extendedTracesMiddleware = ({ behaviour = "auto", instrumentations, logLev
60
62
  processor = extended.processor;
61
63
  break;
62
64
  }
63
- console.warn("unable to extend provider, Extended Traces middleware will not work. Either allow the middleware to create a provider by setting `behaviour: \"createProvider\"` or `behaviour: \"auto\"`, or make sure that the provider is created and imported before the middleware is used.");
65
+ console.warn("unable to extend provider, Extended Traces middleware will not work. Use @inngest/otel, or make sure that the provider is created and imported before the middleware is used.");
64
66
  break;
65
67
  }
66
68
  case "off": break;
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.cjs","names":["debugPrefix","#logger","DiagLogLevel","processor: InngestSpanProcessor | undefined","processorReady: Promise<void> | undefined","extendProvider","createProvider","Middleware","diag","trace","version"],"sources":["../../../../src/components/execution/otel/middleware.ts"],"sourcesContent":["import { type DiagLogger, DiagLogLevel, diag, trace } from \"@opentelemetry/api\";\nimport Debug from \"debug\";\nimport { version } from \"../../../version.ts\";\nimport { Middleware } from \"../../middleware/middleware.ts\";\nimport { clientProcessorMap } from \"./access.ts\";\nimport { debugPrefix } from \"./consts.ts\";\nimport type { InngestSpanProcessor } from \"./processor.ts\";\nimport {\n type Behaviour,\n createProvider,\n extendProvider,\n type Instrumentations,\n} from \"./util.ts\";\n\nconst devDebug = Debug(`${debugPrefix}:middleware`);\n\nclass InngestTracesLogger implements DiagLogger {\n #logger = Debug(`${debugPrefix}:diag`);\n\n debug = this.#logger;\n error = this.#logger;\n info = this.#logger;\n verbose = this.#logger;\n warn = this.#logger;\n}\n\n/**\n * A set of options for the Extended Traces middleware.\n */\nexport interface ExtendedTracesMiddlewareOptions {\n /**\n * The behaviour of the Extended Traces middleware. This controls whether the\n * middleware will create a new OpenTelemetry provider, extend an existing one, or\n * do nothing. The default is \"auto\", which will attempt to extend an\n * existing provider, and if that fails, create a new one.\n *\n * - `\"auto\"`: Attempt to extend an existing provider, and if that fails,\n * create a new one.\n * - `\"createProvider\"`: Create a new OpenTelemetry provider.\n * - `\"extendProvider\"`: Attempt to extend an existing provider.\n * - `\"off\"`: Do nothing.\n */\n behaviour?: Behaviour;\n\n /**\n * Add additional instrumentations to the OpenTelemetry provider.\n *\n * Note that these only apply if the provider is created by the middleware;\n * extending an existing provider cannot add instrumentations and it instead\n * must be done wherever the provider is created.\n */\n instrumentations?: Instrumentations;\n\n /**\n * The log level for the Extended Traces middleware, specifically a diagnostic logger\n * attached to the global OpenTelemetry provider.\n *\n * Defaults to `DiagLogLevel.ERROR`.\n */\n logLevel?: DiagLogLevel;\n}\n\n/**\n * Middleware the captures and exports spans relevant to Inngest runs using\n * OTel.\n *\n * This can be used to attach additional spans and data to the existing traces\n * in your Inngest dashboard (or Dev Server).\n */\nexport const extendedTracesMiddleware = ({\n behaviour = \"auto\",\n instrumentations,\n logLevel = DiagLogLevel.ERROR,\n}: ExtendedTracesMiddlewareOptions = {}) => {\n devDebug(\"behaviour:\", behaviour);\n\n let processor: InngestSpanProcessor | undefined;\n let processorReady: Promise<void> | undefined;\n\n switch (behaviour) {\n case \"auto\": {\n const extended = extendProvider(behaviour);\n if (extended.success) {\n devDebug(\"extended existing provider\");\n processor = extended.processor;\n break;\n }\n\n processorReady = createProvider(behaviour, instrumentations).then(\n (created) => {\n if (created.success) {\n devDebug(\"created new provider\");\n processor = created.processor;\n } else {\n console.warn(\n \"no provider found to extend and unable to create one\",\n created.error ?? \"\",\n );\n }\n },\n );\n\n break;\n }\n case \"createProvider\": {\n processorReady = createProvider(behaviour, instrumentations).then(\n (created) => {\n if (created.success) {\n devDebug(\"created new provider\");\n processor = created.processor;\n } else {\n console.warn(\n \"unable to create provider, Extended Traces middleware will not work\",\n created.error ?? \"\",\n );\n }\n },\n );\n\n break;\n }\n case \"extendProvider\": {\n const extended = extendProvider(behaviour);\n if (extended.success) {\n devDebug(\"extended existing provider\");\n processor = extended.processor;\n break;\n }\n\n console.warn(\n 'unable to extend provider, Extended Traces middleware will not work. Either allow the middleware to create a provider by setting `behaviour: \"createProvider\"` or `behaviour: \"auto\"`, or make sure that the provider is created and imported before the middleware is used.',\n );\n\n break;\n }\n case \"off\": {\n break;\n }\n default: {\n // unknown\n console.warn(\n `unknown behaviour ${JSON.stringify(behaviour)}, defaulting to \"off\"`,\n );\n }\n }\n\n class ExtendedTracesMiddleware extends Middleware.BaseMiddleware {\n readonly id = \"inngest:extended-traces\";\n\n /**\n * Called by the Inngest constructor to associate the processor with the\n * client.\n */\n static override onRegister({ client }: Middleware.OnRegisterArgs) {\n // Set the logger for our otel processors and exporters.\n // If this is called multiple times, only the first call is set.\n devDebug(\n \"set otel diagLogger:\",\n diag.setLogger(new InngestTracesLogger(), logLevel),\n );\n\n if (processor) {\n clientProcessorMap.set(client, processor);\n } else if (processorReady) {\n // createProvider is async; register the processor once it resolves.\n processorReady\n .then(() => {\n if (processor) {\n clientProcessorMap.set(client, processor);\n }\n })\n .catch((err) => {\n devDebug(\"failed to register processor for client:\", err);\n });\n }\n }\n\n override transformFunctionInput(\n arg: Middleware.TransformFunctionInputArgs,\n ) {\n return {\n ...arg,\n ctx: {\n ...arg.ctx,\n tracer: trace.getTracer(\"inngest\", version),\n },\n };\n }\n\n override async wrapRequest({ next }: Middleware.WrapRequestArgs) {\n return next().finally(() => processor?.forceFlush());\n }\n }\n\n return ExtendedTracesMiddleware;\n};\n"],"mappings":";;;;;;;;;;;AAcA,MAAM,8BAAiB,GAAGA,2BAAY,aAAa;AAEnD,IAAM,sBAAN,MAAgD;CAC9C,6BAAgB,GAAGA,2BAAY,OAAO;CAEtC,QAAQ,MAAKC;CACb,QAAQ,MAAKA;CACb,OAAO,MAAKA;CACZ,UAAU,MAAKA;CACf,OAAO,MAAKA;;;;;;;;;AA8Cd,MAAa,4BAA4B,EACvC,YAAY,QACZ,kBACA,WAAWC,iCAAa,UACW,EAAE,KAAK;AAC1C,UAAS,cAAc,UAAU;CAEjC,IAAIC;CACJ,IAAIC;AAEJ,SAAQ,WAAR;EACE,KAAK,QAAQ;GACX,MAAM,WAAWC,4BAAe,UAAU;AAC1C,OAAI,SAAS,SAAS;AACpB,aAAS,6BAA6B;AACtC,gBAAY,SAAS;AACrB;;AAGF,oBAAiBC,4BAAe,WAAW,iBAAiB,CAAC,MAC1D,YAAY;AACX,QAAI,QAAQ,SAAS;AACnB,cAAS,uBAAuB;AAChC,iBAAY,QAAQ;UAEpB,SAAQ,KACN,wDACA,QAAQ,SAAS,GAClB;KAGN;AAED;;EAEF,KAAK;AACH,oBAAiBA,4BAAe,WAAW,iBAAiB,CAAC,MAC1D,YAAY;AACX,QAAI,QAAQ,SAAS;AACnB,cAAS,uBAAuB;AAChC,iBAAY,QAAQ;UAEpB,SAAQ,KACN,uEACA,QAAQ,SAAS,GAClB;KAGN;AAED;EAEF,KAAK,kBAAkB;GACrB,MAAM,WAAWD,4BAAe,UAAU;AAC1C,OAAI,SAAS,SAAS;AACpB,aAAS,6BAA6B;AACtC,gBAAY,SAAS;AACrB;;AAGF,WAAQ,KACN,mRACD;AAED;;EAEF,KAAK,MACH;EAEF,QAEE,SAAQ,KACN,qBAAqB,KAAK,UAAU,UAAU,CAAC,uBAChD;;CAIL,MAAM,iCAAiCE,8BAAW,eAAe;EAC/D,AAAS,KAAK;;;;;EAMd,OAAgB,WAAW,EAAE,UAAqC;AAGhE,YACE,wBACAC,yBAAK,UAAU,IAAI,qBAAqB,EAAE,SAAS,CACpD;AAED,OAAI,UACF,mCAAmB,IAAI,QAAQ,UAAU;YAChC,eAET,gBACG,WAAW;AACV,QAAI,UACF,mCAAmB,IAAI,QAAQ,UAAU;KAE3C,CACD,OAAO,QAAQ;AACd,aAAS,4CAA4C,IAAI;KACzD;;EAIR,AAAS,uBACP,KACA;AACA,UAAO;IACL,GAAG;IACH,KAAK;KACH,GAAG,IAAI;KACP,QAAQC,0BAAM,UAAU,WAAWC,wBAAQ;KAC5C;IACF;;EAGH,MAAe,YAAY,EAAE,QAAoC;AAC/D,UAAO,MAAM,CAAC,cAAc,WAAW,YAAY,CAAC;;;AAIxD,QAAO"}
1
+ {"version":3,"file":"middleware.cjs","names":["debugPrefix","#logger","DiagLogLevel","processor: InngestSpanProcessor | undefined","processorReady: Promise<void> | undefined","extendProvider","createProvider","Middleware","diag","trace","version"],"sources":["../../../../src/components/execution/otel/middleware.ts"],"sourcesContent":["import { type DiagLogger, DiagLogLevel, diag, trace } from \"@opentelemetry/api\";\nimport Debug from \"debug\";\nimport { version } from \"../../../version.ts\";\nimport { Middleware } from \"../../middleware/middleware.ts\";\nimport { clientProcessorMap } from \"./access.ts\";\nimport { debugPrefix } from \"./consts.ts\";\nimport type { InngestSpanProcessor } from \"./processor.ts\";\nimport {\n type Behaviour,\n createProvider,\n extendProvider,\n type Instrumentations,\n warnDeprecatedCreateProviderBehaviour,\n} from \"./util.ts\";\n\nconst devDebug = Debug(`${debugPrefix}:middleware`);\n\nclass InngestTracesLogger implements DiagLogger {\n #logger = Debug(`${debugPrefix}:diag`);\n\n debug = this.#logger;\n error = this.#logger;\n info = this.#logger;\n verbose = this.#logger;\n warn = this.#logger;\n}\n\n/**\n * A set of options for the Extended Traces middleware.\n */\nexport interface ExtendedTracesMiddlewareOptions {\n /**\n * The behaviour of the Extended Traces middleware. This controls whether the\n * middleware will create a new OpenTelemetry provider, extend an existing one, or\n * do nothing. The default is \"auto\", which will attempt to extend an\n * existing provider, and if that fails, use the deprecated provider creation\n * path.\n *\n * - `\"auto\"`: Attempt to extend an existing provider, and if that fails,\n * create a new one using the deprecated provider creation path.\n * - `\"createProvider\"`: Create a new OpenTelemetry provider.\n * Deprecated. Use @inngest/otel and\n * `\"extendProvider\"` instead.\n * - `\"extendProvider\"`: Attempt to extend an existing provider.\n * - `\"off\"`: Do nothing.\n */\n behaviour?: Behaviour;\n\n /**\n * Add additional instrumentations to the OpenTelemetry provider.\n *\n * Note that these only apply when the middleware uses the deprecated provider\n * creation path. Extending an existing provider cannot add instrumentations;\n * configure them wherever the provider is created instead.\n *\n * @deprecated Configure custom instrumentations wherever your OpenTelemetry\n * provider is created. This option only applies to the deprecated provider\n * creation path in `extendedTracesMiddleware`.\n */\n instrumentations?: Instrumentations;\n\n /**\n * The log level for the Extended Traces middleware, specifically a diagnostic logger\n * attached to the global OpenTelemetry provider.\n *\n * Defaults to `DiagLogLevel.ERROR`.\n */\n logLevel?: DiagLogLevel;\n}\n\n/**\n * Middleware the captures and exports spans relevant to Inngest runs using\n * OTel.\n *\n * This can be used to attach additional spans and data to the existing traces\n * in your Inngest dashboard (or Dev Server).\n */\nexport const extendedTracesMiddleware = ({\n behaviour = \"auto\",\n instrumentations,\n logLevel = DiagLogLevel.ERROR,\n}: ExtendedTracesMiddlewareOptions = {}) => {\n devDebug(\"behaviour:\", behaviour);\n\n let processor: InngestSpanProcessor | undefined;\n let processorReady: Promise<void> | undefined;\n\n switch (behaviour) {\n case \"auto\": {\n const extended = extendProvider(behaviour);\n if (extended.success) {\n devDebug(\"extended existing provider\");\n processor = extended.processor;\n break;\n }\n\n warnDeprecatedCreateProviderBehaviour(behaviour);\n processorReady = createProvider(behaviour, instrumentations).then(\n (created) => {\n if (created.success) {\n devDebug(\"created new provider\");\n processor = created.processor;\n } else {\n console.warn(\n \"no provider found to extend and unable to create one\",\n created.error ?? \"\",\n );\n }\n },\n );\n\n break;\n }\n case \"createProvider\": {\n warnDeprecatedCreateProviderBehaviour(behaviour);\n processorReady = createProvider(behaviour, instrumentations).then(\n (created) => {\n if (created.success) {\n devDebug(\"created new provider\");\n processor = created.processor;\n } else {\n console.warn(\n \"unable to create provider, Extended Traces middleware will not work\",\n created.error ?? \"\",\n );\n }\n },\n );\n\n break;\n }\n case \"extendProvider\": {\n const extended = extendProvider(behaviour);\n if (extended.success) {\n devDebug(\"extended existing provider\");\n processor = extended.processor;\n break;\n }\n\n console.warn(\n \"unable to extend provider, Extended Traces middleware will not work. Use @inngest/otel, or make sure that the provider is created and imported before the middleware is used.\",\n );\n\n break;\n }\n case \"off\": {\n break;\n }\n default: {\n // unknown\n console.warn(\n `unknown behaviour ${JSON.stringify(behaviour)}, defaulting to \"off\"`,\n );\n }\n }\n\n class ExtendedTracesMiddleware extends Middleware.BaseMiddleware {\n readonly id = \"inngest:extended-traces\";\n\n /**\n * Called by the Inngest constructor to associate the processor with the\n * client.\n */\n static override onRegister({ client }: Middleware.OnRegisterArgs) {\n // Set the logger for our otel processors and exporters.\n // If this is called multiple times, only the first call is set.\n devDebug(\n \"set otel diagLogger:\",\n diag.setLogger(new InngestTracesLogger(), logLevel),\n );\n\n if (processor) {\n clientProcessorMap.set(client, processor);\n } else if (processorReady) {\n // Provider creation is async; register the processor once it resolves.\n processorReady\n .then(() => {\n if (processor) {\n clientProcessorMap.set(client, processor);\n }\n })\n .catch((err) => {\n devDebug(\"failed to register processor for client:\", err);\n });\n }\n }\n\n override transformFunctionInput(\n arg: Middleware.TransformFunctionInputArgs,\n ) {\n return {\n ...arg,\n ctx: {\n ...arg.ctx,\n tracer: trace.getTracer(\"inngest\", version),\n },\n };\n }\n\n override async wrapRequest({ next }: Middleware.WrapRequestArgs) {\n return next().finally(() => processor?.forceFlush());\n }\n }\n\n return ExtendedTracesMiddleware;\n};\n"],"mappings":";;;;;;;;;;;AAeA,MAAM,8BAAiB,GAAGA,2BAAY,aAAa;AAEnD,IAAM,sBAAN,MAAgD;CAC9C,6BAAgB,GAAGA,2BAAY,OAAO;CAEtC,QAAQ,MAAKC;CACb,QAAQ,MAAKA;CACb,OAAO,MAAKA;CACZ,UAAU,MAAKA;CACf,OAAO,MAAKA;;;;;;;;;AAqDd,MAAa,4BAA4B,EACvC,YAAY,QACZ,kBACA,WAAWC,iCAAa,UACW,EAAE,KAAK;AAC1C,UAAS,cAAc,UAAU;CAEjC,IAAIC;CACJ,IAAIC;AAEJ,SAAQ,WAAR;EACE,KAAK,QAAQ;GACX,MAAM,WAAWC,4BAAe,UAAU;AAC1C,OAAI,SAAS,SAAS;AACpB,aAAS,6BAA6B;AACtC,gBAAY,SAAS;AACrB;;AAGF,sDAAsC,UAAU;AAChD,oBAAiBC,4BAAe,WAAW,iBAAiB,CAAC,MAC1D,YAAY;AACX,QAAI,QAAQ,SAAS;AACnB,cAAS,uBAAuB;AAChC,iBAAY,QAAQ;UAEpB,SAAQ,KACN,wDACA,QAAQ,SAAS,GAClB;KAGN;AAED;;EAEF,KAAK;AACH,sDAAsC,UAAU;AAChD,oBAAiBA,4BAAe,WAAW,iBAAiB,CAAC,MAC1D,YAAY;AACX,QAAI,QAAQ,SAAS;AACnB,cAAS,uBAAuB;AAChC,iBAAY,QAAQ;UAEpB,SAAQ,KACN,uEACA,QAAQ,SAAS,GAClB;KAGN;AAED;EAEF,KAAK,kBAAkB;GACrB,MAAM,WAAWD,4BAAe,UAAU;AAC1C,OAAI,SAAS,SAAS;AACpB,aAAS,6BAA6B;AACtC,gBAAY,SAAS;AACrB;;AAGF,WAAQ,KACN,gLACD;AAED;;EAEF,KAAK,MACH;EAEF,QAEE,SAAQ,KACN,qBAAqB,KAAK,UAAU,UAAU,CAAC,uBAChD;;CAIL,MAAM,iCAAiCE,8BAAW,eAAe;EAC/D,AAAS,KAAK;;;;;EAMd,OAAgB,WAAW,EAAE,UAAqC;AAGhE,YACE,wBACAC,yBAAK,UAAU,IAAI,qBAAqB,EAAE,SAAS,CACpD;AAED,OAAI,UACF,mCAAmB,IAAI,QAAQ,UAAU;YAChC,eAET,gBACG,WAAW;AACV,QAAI,UACF,mCAAmB,IAAI,QAAQ,UAAU;KAE3C,CACD,OAAO,QAAQ;AACd,aAAS,4CAA4C,IAAI;KACzD;;EAIR,AAAS,uBACP,KACA;AACA,UAAO;IACL,GAAG;IACH,KAAK;KACH,GAAG,IAAI;KACP,QAAQC,0BAAM,UAAU,WAAWC,wBAAQ;KAC5C;IACF;;EAGH,MAAe,YAAY,EAAE,QAAoC;AAC/D,UAAO,MAAM,CAAC,cAAc,WAAW,YAAY,CAAC;;;AAIxD,QAAO"}
@@ -1,12 +1,12 @@
1
1
  import { InngestApi } from "../../../api/api.cjs";
2
2
  import { AsTuple, ExclusiveKeys, MaybePromise, SendEventPayload, Simplify } from "../../../helpers/types.cjs";
3
- import { StepFetch } from "../../Fetch.cjs";
4
3
  import { Jsonify } from "../../../helpers/jsonify.cjs";
4
+ import { StepFetch } from "../../Fetch.cjs";
5
5
  import { DurationLike, InstantLike, ZonedDateTimeLike } from "../../../helpers/temporal.cjs";
6
6
  import { createGroupTools } from "../../InngestGroupTools.cjs";
7
- import { Middleware } from "../../middleware/middleware.cjs";
8
7
  import { Realtime } from "../../realtime/types.cjs";
9
8
  import { EventType } from "../../triggers/triggers.cjs";
9
+ import { Middleware } from "../../middleware/middleware.cjs";
10
10
  import { InngestFunction } from "../../InngestFunction.cjs";
11
11
  import { ClientOptions, DeferFn, EventMeta, EventPayload, InvocationResult, InvokeTargetFunctionDefinition, JsonError, ReceivedEventMeta, SendEventBaseOutput, SendEventOutput, StepOptionsOrId, TimeStr, TimeStrBatch, TriggerEventFromFunction } from "../../../types.cjs";
12
12
  import { GetFunctionOutputRaw, Inngest } from "../../Inngest.cjs";
@@ -25,11 +25,14 @@ interface ExtendedTracesMiddlewareOptions {
25
25
  * The behaviour of the Extended Traces middleware. This controls whether the
26
26
  * middleware will create a new OpenTelemetry provider, extend an existing one, or
27
27
  * do nothing. The default is "auto", which will attempt to extend an
28
- * existing provider, and if that fails, create a new one.
28
+ * existing provider, and if that fails, use the deprecated provider creation
29
+ * path.
29
30
  *
30
31
  * - `"auto"`: Attempt to extend an existing provider, and if that fails,
31
- * create a new one.
32
+ * create a new one using the deprecated provider creation path.
32
33
  * - `"createProvider"`: Create a new OpenTelemetry provider.
34
+ * Deprecated. Use @inngest/otel and
35
+ * `"extendProvider"` instead.
33
36
  * - `"extendProvider"`: Attempt to extend an existing provider.
34
37
  * - `"off"`: Do nothing.
35
38
  */
@@ -37,9 +40,13 @@ interface ExtendedTracesMiddlewareOptions {
37
40
  /**
38
41
  * Add additional instrumentations to the OpenTelemetry provider.
39
42
  *
40
- * Note that these only apply if the provider is created by the middleware;
41
- * extending an existing provider cannot add instrumentations and it instead
42
- * must be done wherever the provider is created.
43
+ * Note that these only apply when the middleware uses the deprecated provider
44
+ * creation path. Extending an existing provider cannot add instrumentations;
45
+ * configure them wherever the provider is created instead.
46
+ *
47
+ * @deprecated Configure custom instrumentations wherever your OpenTelemetry
48
+ * provider is created. This option only applies to the deprecated provider
49
+ * creation path in `extendedTracesMiddleware`.
43
50
  */
44
51
  instrumentations?: Instrumentations;
45
52
  /**
@@ -72,6 +79,11 @@ declare const extendedTracesMiddleware: ({
72
79
  ctx: {
73
80
  tracer: _opentelemetry_api0.Tracer;
74
81
  event: Simplify<EventPayload>;
82
+ defer: DeferFn;
83
+ events: AsTuple<Simplify<EventPayload>>;
84
+ runId: string;
85
+ requestId?: string | undefined;
86
+ jobId?: string | undefined;
75
87
  step: {
76
88
  sendEvent: (idOrOptions: StepOptionsOrId, payload: SendEventPayload) => Promise<SendEventOutput<ClientOptions>>;
77
89
  waitForSignal: <TData>(idOrOptions: StepOptionsOrId, opts: {
@@ -158,11 +170,6 @@ declare const extendedTracesMiddleware: ({
158
170
  }) => InvocationResult<Jsonify<GetFunctionOutputRaw<TFunction>>>;
159
171
  fetch: StepFetch;
160
172
  };
161
- defer: DeferFn;
162
- events: AsTuple<Simplify<EventPayload>>;
163
- runId: string;
164
- requestId?: string | undefined;
165
- jobId?: string | undefined;
166
173
  group: ReturnType<typeof createGroupTools>;
167
174
  attempt: number;
168
175
  maxAttempts?: number | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.cts","names":[],"sources":["../../../../src/components/execution/otel/middleware.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;UA6BiB,+BAAA;;;;;;;;;;;;;EAAA,SAAA,CAAA,EAaH,SAbG;EAA+B;;;;;AAwChD;;kBAAyC,CAAA,EAlBpB,gBAkBoB;;;;;;;UA6GO,CAAA,EAvHnC,YAuHmC;;;;;;;;;cA7GnC;;;;IAIV;;;;;;;gCAyGQ,UAAA,CAAW;;gBAA0B,mBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAWI,EAAA,CAAA,EAAA,MAAA;gBAAe,CAAA,CAAA,EAAA,MAAA;gBAAA,IAAA,CAAA,WAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YApCb,CAAA,GAAA,SAAA;YAAc,SAAA,aAAA,CAAA,EAAA,MAAA,GAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoC3B,UAAA,CAAW,kBAAe,QAAA,UAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;KApCxB,UAAA,CAAW"}
1
+ {"version":3,"file":"middleware.d.cts","names":[],"sources":["../../../../src/components/execution/otel/middleware.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;UA8BiB,+BAAA;;;;;;;;;;;;;AAAjB;;;WA6BqB,CAAA,EAbP,SAaO;;;AAkBrB;;;;;;;;;kBA+GgD,CAAA,EAjI3B,gBAiI2B;;;;;;;aAzHnC;;;;;;;;;cAUA;;;;IAIV;;;;;;;gCA2GQ,UAAA,CAAW;;gBAA0B,mBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAWI,SAAA,KAAA,EAAA,MAAA,GAAA;cAAe,SAAA,KAAA,EAAA,MAAA;cAAA,SAAA,IAAA,EAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UApCb,SAAA,OAAA,CAAA,EAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,SAAA;UAAc,SAAA,SAAA,CAAA,EAAA,GAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoC3B,UAAA,CAAW,kBAAe,QAAA,UAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;KApCxB,UAAA,CAAW"}
@@ -1,12 +1,12 @@
1
1
  import { InngestApi } from "../../../api/api.js";
2
2
  import { AsTuple, ExclusiveKeys, MaybePromise, SendEventPayload, Simplify } from "../../../helpers/types.js";
3
- import { StepFetch } from "../../Fetch.js";
4
3
  import { Jsonify } from "../../../helpers/jsonify.js";
4
+ import { StepFetch } from "../../Fetch.js";
5
5
  import { DurationLike, InstantLike, ZonedDateTimeLike } from "../../../helpers/temporal.js";
6
6
  import { createGroupTools } from "../../InngestGroupTools.js";
7
- import { Middleware } from "../../middleware/middleware.js";
8
7
  import { Realtime } from "../../realtime/types.js";
9
8
  import { EventType } from "../../triggers/triggers.js";
9
+ import { Middleware } from "../../middleware/middleware.js";
10
10
  import { InngestFunction } from "../../InngestFunction.js";
11
11
  import { ClientOptions, DeferFn, EventMeta, EventPayload, InvocationResult, InvokeTargetFunctionDefinition, JsonError, ReceivedEventMeta, SendEventBaseOutput, SendEventOutput, StepOptionsOrId, TimeStr, TimeStrBatch, TriggerEventFromFunction } from "../../../types.js";
12
12
  import { GetFunctionOutputRaw, Inngest } from "../../Inngest.js";
@@ -25,11 +25,14 @@ interface ExtendedTracesMiddlewareOptions {
25
25
  * The behaviour of the Extended Traces middleware. This controls whether the
26
26
  * middleware will create a new OpenTelemetry provider, extend an existing one, or
27
27
  * do nothing. The default is "auto", which will attempt to extend an
28
- * existing provider, and if that fails, create a new one.
28
+ * existing provider, and if that fails, use the deprecated provider creation
29
+ * path.
29
30
  *
30
31
  * - `"auto"`: Attempt to extend an existing provider, and if that fails,
31
- * create a new one.
32
+ * create a new one using the deprecated provider creation path.
32
33
  * - `"createProvider"`: Create a new OpenTelemetry provider.
34
+ * Deprecated. Use @inngest/otel and
35
+ * `"extendProvider"` instead.
33
36
  * - `"extendProvider"`: Attempt to extend an existing provider.
34
37
  * - `"off"`: Do nothing.
35
38
  */
@@ -37,9 +40,13 @@ interface ExtendedTracesMiddlewareOptions {
37
40
  /**
38
41
  * Add additional instrumentations to the OpenTelemetry provider.
39
42
  *
40
- * Note that these only apply if the provider is created by the middleware;
41
- * extending an existing provider cannot add instrumentations and it instead
42
- * must be done wherever the provider is created.
43
+ * Note that these only apply when the middleware uses the deprecated provider
44
+ * creation path. Extending an existing provider cannot add instrumentations;
45
+ * configure them wherever the provider is created instead.
46
+ *
47
+ * @deprecated Configure custom instrumentations wherever your OpenTelemetry
48
+ * provider is created. This option only applies to the deprecated provider
49
+ * creation path in `extendedTracesMiddleware`.
43
50
  */
44
51
  instrumentations?: Instrumentations;
45
52
  /**
@@ -72,6 +79,11 @@ declare const extendedTracesMiddleware: ({
72
79
  ctx: {
73
80
  tracer: _opentelemetry_api0.Tracer;
74
81
  event: Simplify<EventPayload>;
82
+ defer: DeferFn;
83
+ events: AsTuple<Simplify<EventPayload>>;
84
+ runId: string;
85
+ requestId?: string | undefined;
86
+ jobId?: string | undefined;
75
87
  step: {
76
88
  sendEvent: (idOrOptions: StepOptionsOrId, payload: SendEventPayload) => Promise<SendEventOutput<ClientOptions>>;
77
89
  waitForSignal: <TData>(idOrOptions: StepOptionsOrId, opts: {
@@ -158,11 +170,6 @@ declare const extendedTracesMiddleware: ({
158
170
  }) => InvocationResult<Jsonify<GetFunctionOutputRaw<TFunction>>>;
159
171
  fetch: StepFetch;
160
172
  };
161
- defer: DeferFn;
162
- events: AsTuple<Simplify<EventPayload>>;
163
- runId: string;
164
- requestId?: string | undefined;
165
- jobId?: string | undefined;
166
173
  group: ReturnType<typeof createGroupTools>;
167
174
  attempt: number;
168
175
  maxAttempts?: number | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","names":[],"sources":["../../../../src/components/execution/otel/middleware.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;UA6BiB,+BAAA;;;;;;;;;;;;;EAAA,SAAA,CAAA,EAaH,SAbG;EAA+B;;;;;AAwChD;;kBAAyC,CAAA,EAlBpB,gBAkBoB;;;;;;;UA6GO,CAAA,EAvHnC,YAuHmC;;;;;;;;;cA7GnC;;;;IAIV;;;;;;;gCAyGQ,UAAA,CAAW;;gBAA0B,mBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAWI,EAAA,CAAA,EAAA,MAAA;gBAAe,CAAA,CAAA,EAAA,MAAA;gBAAA,IAAA,CAAA,WAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YApCb,CAAA,GAAA,SAAA;YAAc,SAAA,aAAA,CAAA,EAAA,MAAA,GAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoC3B,UAAA,CAAW,kBAAe,QAAA,UAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;KApCxB,UAAA,CAAW"}
1
+ {"version":3,"file":"middleware.d.ts","names":[],"sources":["../../../../src/components/execution/otel/middleware.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;UA8BiB,+BAAA;;;;;;;;;;;;;AAAjB;;;WA6BqB,CAAA,EAbP,SAaO;;;AAkBrB;;;;;;;;;kBA+GgD,CAAA,EAjI3B,gBAiI2B;;;;;;;aAzHnC;;;;;;;;;cAUA;;;;IAIV;;;;;;;gCA2GQ,UAAA,CAAW;;gBAA0B,mBAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAWI,SAAA,KAAA,EAAA,MAAA,GAAA;cAAe,SAAA,KAAA,EAAA,MAAA;cAAA,SAAA,IAAA,EAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UApCb,SAAA,OAAA,CAAA,EAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,SAAA;UAAc,SAAA,SAAA,CAAA,EAAA,GAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoC3B,UAAA,CAAW,kBAAe,QAAA,UAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;KApCxB,UAAA,CAAW"}
@@ -2,7 +2,7 @@ import { version } from "../../../version.js";
2
2
  import { debugPrefix } from "./consts.js";
3
3
  import { Middleware } from "../../middleware/middleware.js";
4
4
  import { clientProcessorMap } from "./access.js";
5
- import { createProvider, extendProvider } from "./util.js";
5
+ import { createProvider, extendProvider, warnDeprecatedCreateProviderBehaviour } from "./util.js";
6
6
  import Debug from "debug";
7
7
  import { DiagLogLevel, diag, trace } from "@opentelemetry/api";
8
8
 
@@ -35,6 +35,7 @@ const extendedTracesMiddleware = ({ behaviour = "auto", instrumentations, logLev
35
35
  processor = extended.processor;
36
36
  break;
37
37
  }
38
+ warnDeprecatedCreateProviderBehaviour(behaviour);
38
39
  processorReady = createProvider(behaviour, instrumentations).then((created) => {
39
40
  if (created.success) {
40
41
  devDebug("created new provider");
@@ -44,6 +45,7 @@ const extendedTracesMiddleware = ({ behaviour = "auto", instrumentations, logLev
44
45
  break;
45
46
  }
46
47
  case "createProvider":
48
+ warnDeprecatedCreateProviderBehaviour(behaviour);
47
49
  processorReady = createProvider(behaviour, instrumentations).then((created) => {
48
50
  if (created.success) {
49
51
  devDebug("created new provider");
@@ -58,7 +60,7 @@ const extendedTracesMiddleware = ({ behaviour = "auto", instrumentations, logLev
58
60
  processor = extended.processor;
59
61
  break;
60
62
  }
61
- console.warn("unable to extend provider, Extended Traces middleware will not work. Either allow the middleware to create a provider by setting `behaviour: \"createProvider\"` or `behaviour: \"auto\"`, or make sure that the provider is created and imported before the middleware is used.");
63
+ console.warn("unable to extend provider, Extended Traces middleware will not work. Use @inngest/otel, or make sure that the provider is created and imported before the middleware is used.");
62
64
  break;
63
65
  }
64
66
  case "off": break;
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","names":["#logger","processor: InngestSpanProcessor | undefined","processorReady: Promise<void> | undefined"],"sources":["../../../../src/components/execution/otel/middleware.ts"],"sourcesContent":["import { type DiagLogger, DiagLogLevel, diag, trace } from \"@opentelemetry/api\";\nimport Debug from \"debug\";\nimport { version } from \"../../../version.ts\";\nimport { Middleware } from \"../../middleware/middleware.ts\";\nimport { clientProcessorMap } from \"./access.ts\";\nimport { debugPrefix } from \"./consts.ts\";\nimport type { InngestSpanProcessor } from \"./processor.ts\";\nimport {\n type Behaviour,\n createProvider,\n extendProvider,\n type Instrumentations,\n} from \"./util.ts\";\n\nconst devDebug = Debug(`${debugPrefix}:middleware`);\n\nclass InngestTracesLogger implements DiagLogger {\n #logger = Debug(`${debugPrefix}:diag`);\n\n debug = this.#logger;\n error = this.#logger;\n info = this.#logger;\n verbose = this.#logger;\n warn = this.#logger;\n}\n\n/**\n * A set of options for the Extended Traces middleware.\n */\nexport interface ExtendedTracesMiddlewareOptions {\n /**\n * The behaviour of the Extended Traces middleware. This controls whether the\n * middleware will create a new OpenTelemetry provider, extend an existing one, or\n * do nothing. The default is \"auto\", which will attempt to extend an\n * existing provider, and if that fails, create a new one.\n *\n * - `\"auto\"`: Attempt to extend an existing provider, and if that fails,\n * create a new one.\n * - `\"createProvider\"`: Create a new OpenTelemetry provider.\n * - `\"extendProvider\"`: Attempt to extend an existing provider.\n * - `\"off\"`: Do nothing.\n */\n behaviour?: Behaviour;\n\n /**\n * Add additional instrumentations to the OpenTelemetry provider.\n *\n * Note that these only apply if the provider is created by the middleware;\n * extending an existing provider cannot add instrumentations and it instead\n * must be done wherever the provider is created.\n */\n instrumentations?: Instrumentations;\n\n /**\n * The log level for the Extended Traces middleware, specifically a diagnostic logger\n * attached to the global OpenTelemetry provider.\n *\n * Defaults to `DiagLogLevel.ERROR`.\n */\n logLevel?: DiagLogLevel;\n}\n\n/**\n * Middleware the captures and exports spans relevant to Inngest runs using\n * OTel.\n *\n * This can be used to attach additional spans and data to the existing traces\n * in your Inngest dashboard (or Dev Server).\n */\nexport const extendedTracesMiddleware = ({\n behaviour = \"auto\",\n instrumentations,\n logLevel = DiagLogLevel.ERROR,\n}: ExtendedTracesMiddlewareOptions = {}) => {\n devDebug(\"behaviour:\", behaviour);\n\n let processor: InngestSpanProcessor | undefined;\n let processorReady: Promise<void> | undefined;\n\n switch (behaviour) {\n case \"auto\": {\n const extended = extendProvider(behaviour);\n if (extended.success) {\n devDebug(\"extended existing provider\");\n processor = extended.processor;\n break;\n }\n\n processorReady = createProvider(behaviour, instrumentations).then(\n (created) => {\n if (created.success) {\n devDebug(\"created new provider\");\n processor = created.processor;\n } else {\n console.warn(\n \"no provider found to extend and unable to create one\",\n created.error ?? \"\",\n );\n }\n },\n );\n\n break;\n }\n case \"createProvider\": {\n processorReady = createProvider(behaviour, instrumentations).then(\n (created) => {\n if (created.success) {\n devDebug(\"created new provider\");\n processor = created.processor;\n } else {\n console.warn(\n \"unable to create provider, Extended Traces middleware will not work\",\n created.error ?? \"\",\n );\n }\n },\n );\n\n break;\n }\n case \"extendProvider\": {\n const extended = extendProvider(behaviour);\n if (extended.success) {\n devDebug(\"extended existing provider\");\n processor = extended.processor;\n break;\n }\n\n console.warn(\n 'unable to extend provider, Extended Traces middleware will not work. Either allow the middleware to create a provider by setting `behaviour: \"createProvider\"` or `behaviour: \"auto\"`, or make sure that the provider is created and imported before the middleware is used.',\n );\n\n break;\n }\n case \"off\": {\n break;\n }\n default: {\n // unknown\n console.warn(\n `unknown behaviour ${JSON.stringify(behaviour)}, defaulting to \"off\"`,\n );\n }\n }\n\n class ExtendedTracesMiddleware extends Middleware.BaseMiddleware {\n readonly id = \"inngest:extended-traces\";\n\n /**\n * Called by the Inngest constructor to associate the processor with the\n * client.\n */\n static override onRegister({ client }: Middleware.OnRegisterArgs) {\n // Set the logger for our otel processors and exporters.\n // If this is called multiple times, only the first call is set.\n devDebug(\n \"set otel diagLogger:\",\n diag.setLogger(new InngestTracesLogger(), logLevel),\n );\n\n if (processor) {\n clientProcessorMap.set(client, processor);\n } else if (processorReady) {\n // createProvider is async; register the processor once it resolves.\n processorReady\n .then(() => {\n if (processor) {\n clientProcessorMap.set(client, processor);\n }\n })\n .catch((err) => {\n devDebug(\"failed to register processor for client:\", err);\n });\n }\n }\n\n override transformFunctionInput(\n arg: Middleware.TransformFunctionInputArgs,\n ) {\n return {\n ...arg,\n ctx: {\n ...arg.ctx,\n tracer: trace.getTracer(\"inngest\", version),\n },\n };\n }\n\n override async wrapRequest({ next }: Middleware.WrapRequestArgs) {\n return next().finally(() => processor?.forceFlush());\n }\n }\n\n return ExtendedTracesMiddleware;\n};\n"],"mappings":";;;;;;;;;AAcA,MAAM,WAAW,MAAM,GAAG,YAAY,aAAa;AAEnD,IAAM,sBAAN,MAAgD;CAC9C,UAAU,MAAM,GAAG,YAAY,OAAO;CAEtC,QAAQ,MAAKA;CACb,QAAQ,MAAKA;CACb,OAAO,MAAKA;CACZ,UAAU,MAAKA;CACf,OAAO,MAAKA;;;;;;;;;AA8Cd,MAAa,4BAA4B,EACvC,YAAY,QACZ,kBACA,WAAW,aAAa,UACW,EAAE,KAAK;AAC1C,UAAS,cAAc,UAAU;CAEjC,IAAIC;CACJ,IAAIC;AAEJ,SAAQ,WAAR;EACE,KAAK,QAAQ;GACX,MAAM,WAAW,eAAe,UAAU;AAC1C,OAAI,SAAS,SAAS;AACpB,aAAS,6BAA6B;AACtC,gBAAY,SAAS;AACrB;;AAGF,oBAAiB,eAAe,WAAW,iBAAiB,CAAC,MAC1D,YAAY;AACX,QAAI,QAAQ,SAAS;AACnB,cAAS,uBAAuB;AAChC,iBAAY,QAAQ;UAEpB,SAAQ,KACN,wDACA,QAAQ,SAAS,GAClB;KAGN;AAED;;EAEF,KAAK;AACH,oBAAiB,eAAe,WAAW,iBAAiB,CAAC,MAC1D,YAAY;AACX,QAAI,QAAQ,SAAS;AACnB,cAAS,uBAAuB;AAChC,iBAAY,QAAQ;UAEpB,SAAQ,KACN,uEACA,QAAQ,SAAS,GAClB;KAGN;AAED;EAEF,KAAK,kBAAkB;GACrB,MAAM,WAAW,eAAe,UAAU;AAC1C,OAAI,SAAS,SAAS;AACpB,aAAS,6BAA6B;AACtC,gBAAY,SAAS;AACrB;;AAGF,WAAQ,KACN,mRACD;AAED;;EAEF,KAAK,MACH;EAEF,QAEE,SAAQ,KACN,qBAAqB,KAAK,UAAU,UAAU,CAAC,uBAChD;;CAIL,MAAM,iCAAiC,WAAW,eAAe;EAC/D,AAAS,KAAK;;;;;EAMd,OAAgB,WAAW,EAAE,UAAqC;AAGhE,YACE,wBACA,KAAK,UAAU,IAAI,qBAAqB,EAAE,SAAS,CACpD;AAED,OAAI,UACF,oBAAmB,IAAI,QAAQ,UAAU;YAChC,eAET,gBACG,WAAW;AACV,QAAI,UACF,oBAAmB,IAAI,QAAQ,UAAU;KAE3C,CACD,OAAO,QAAQ;AACd,aAAS,4CAA4C,IAAI;KACzD;;EAIR,AAAS,uBACP,KACA;AACA,UAAO;IACL,GAAG;IACH,KAAK;KACH,GAAG,IAAI;KACP,QAAQ,MAAM,UAAU,WAAW,QAAQ;KAC5C;IACF;;EAGH,MAAe,YAAY,EAAE,QAAoC;AAC/D,UAAO,MAAM,CAAC,cAAc,WAAW,YAAY,CAAC;;;AAIxD,QAAO"}
1
+ {"version":3,"file":"middleware.js","names":["#logger","processor: InngestSpanProcessor | undefined","processorReady: Promise<void> | undefined"],"sources":["../../../../src/components/execution/otel/middleware.ts"],"sourcesContent":["import { type DiagLogger, DiagLogLevel, diag, trace } from \"@opentelemetry/api\";\nimport Debug from \"debug\";\nimport { version } from \"../../../version.ts\";\nimport { Middleware } from \"../../middleware/middleware.ts\";\nimport { clientProcessorMap } from \"./access.ts\";\nimport { debugPrefix } from \"./consts.ts\";\nimport type { InngestSpanProcessor } from \"./processor.ts\";\nimport {\n type Behaviour,\n createProvider,\n extendProvider,\n type Instrumentations,\n warnDeprecatedCreateProviderBehaviour,\n} from \"./util.ts\";\n\nconst devDebug = Debug(`${debugPrefix}:middleware`);\n\nclass InngestTracesLogger implements DiagLogger {\n #logger = Debug(`${debugPrefix}:diag`);\n\n debug = this.#logger;\n error = this.#logger;\n info = this.#logger;\n verbose = this.#logger;\n warn = this.#logger;\n}\n\n/**\n * A set of options for the Extended Traces middleware.\n */\nexport interface ExtendedTracesMiddlewareOptions {\n /**\n * The behaviour of the Extended Traces middleware. This controls whether the\n * middleware will create a new OpenTelemetry provider, extend an existing one, or\n * do nothing. The default is \"auto\", which will attempt to extend an\n * existing provider, and if that fails, use the deprecated provider creation\n * path.\n *\n * - `\"auto\"`: Attempt to extend an existing provider, and if that fails,\n * create a new one using the deprecated provider creation path.\n * - `\"createProvider\"`: Create a new OpenTelemetry provider.\n * Deprecated. Use @inngest/otel and\n * `\"extendProvider\"` instead.\n * - `\"extendProvider\"`: Attempt to extend an existing provider.\n * - `\"off\"`: Do nothing.\n */\n behaviour?: Behaviour;\n\n /**\n * Add additional instrumentations to the OpenTelemetry provider.\n *\n * Note that these only apply when the middleware uses the deprecated provider\n * creation path. Extending an existing provider cannot add instrumentations;\n * configure them wherever the provider is created instead.\n *\n * @deprecated Configure custom instrumentations wherever your OpenTelemetry\n * provider is created. This option only applies to the deprecated provider\n * creation path in `extendedTracesMiddleware`.\n */\n instrumentations?: Instrumentations;\n\n /**\n * The log level for the Extended Traces middleware, specifically a diagnostic logger\n * attached to the global OpenTelemetry provider.\n *\n * Defaults to `DiagLogLevel.ERROR`.\n */\n logLevel?: DiagLogLevel;\n}\n\n/**\n * Middleware the captures and exports spans relevant to Inngest runs using\n * OTel.\n *\n * This can be used to attach additional spans and data to the existing traces\n * in your Inngest dashboard (or Dev Server).\n */\nexport const extendedTracesMiddleware = ({\n behaviour = \"auto\",\n instrumentations,\n logLevel = DiagLogLevel.ERROR,\n}: ExtendedTracesMiddlewareOptions = {}) => {\n devDebug(\"behaviour:\", behaviour);\n\n let processor: InngestSpanProcessor | undefined;\n let processorReady: Promise<void> | undefined;\n\n switch (behaviour) {\n case \"auto\": {\n const extended = extendProvider(behaviour);\n if (extended.success) {\n devDebug(\"extended existing provider\");\n processor = extended.processor;\n break;\n }\n\n warnDeprecatedCreateProviderBehaviour(behaviour);\n processorReady = createProvider(behaviour, instrumentations).then(\n (created) => {\n if (created.success) {\n devDebug(\"created new provider\");\n processor = created.processor;\n } else {\n console.warn(\n \"no provider found to extend and unable to create one\",\n created.error ?? \"\",\n );\n }\n },\n );\n\n break;\n }\n case \"createProvider\": {\n warnDeprecatedCreateProviderBehaviour(behaviour);\n processorReady = createProvider(behaviour, instrumentations).then(\n (created) => {\n if (created.success) {\n devDebug(\"created new provider\");\n processor = created.processor;\n } else {\n console.warn(\n \"unable to create provider, Extended Traces middleware will not work\",\n created.error ?? \"\",\n );\n }\n },\n );\n\n break;\n }\n case \"extendProvider\": {\n const extended = extendProvider(behaviour);\n if (extended.success) {\n devDebug(\"extended existing provider\");\n processor = extended.processor;\n break;\n }\n\n console.warn(\n \"unable to extend provider, Extended Traces middleware will not work. Use @inngest/otel, or make sure that the provider is created and imported before the middleware is used.\",\n );\n\n break;\n }\n case \"off\": {\n break;\n }\n default: {\n // unknown\n console.warn(\n `unknown behaviour ${JSON.stringify(behaviour)}, defaulting to \"off\"`,\n );\n }\n }\n\n class ExtendedTracesMiddleware extends Middleware.BaseMiddleware {\n readonly id = \"inngest:extended-traces\";\n\n /**\n * Called by the Inngest constructor to associate the processor with the\n * client.\n */\n static override onRegister({ client }: Middleware.OnRegisterArgs) {\n // Set the logger for our otel processors and exporters.\n // If this is called multiple times, only the first call is set.\n devDebug(\n \"set otel diagLogger:\",\n diag.setLogger(new InngestTracesLogger(), logLevel),\n );\n\n if (processor) {\n clientProcessorMap.set(client, processor);\n } else if (processorReady) {\n // Provider creation is async; register the processor once it resolves.\n processorReady\n .then(() => {\n if (processor) {\n clientProcessorMap.set(client, processor);\n }\n })\n .catch((err) => {\n devDebug(\"failed to register processor for client:\", err);\n });\n }\n }\n\n override transformFunctionInput(\n arg: Middleware.TransformFunctionInputArgs,\n ) {\n return {\n ...arg,\n ctx: {\n ...arg.ctx,\n tracer: trace.getTracer(\"inngest\", version),\n },\n };\n }\n\n override async wrapRequest({ next }: Middleware.WrapRequestArgs) {\n return next().finally(() => processor?.forceFlush());\n }\n }\n\n return ExtendedTracesMiddleware;\n};\n"],"mappings":";;;;;;;;;AAeA,MAAM,WAAW,MAAM,GAAG,YAAY,aAAa;AAEnD,IAAM,sBAAN,MAAgD;CAC9C,UAAU,MAAM,GAAG,YAAY,OAAO;CAEtC,QAAQ,MAAKA;CACb,QAAQ,MAAKA;CACb,OAAO,MAAKA;CACZ,UAAU,MAAKA;CACf,OAAO,MAAKA;;;;;;;;;AAqDd,MAAa,4BAA4B,EACvC,YAAY,QACZ,kBACA,WAAW,aAAa,UACW,EAAE,KAAK;AAC1C,UAAS,cAAc,UAAU;CAEjC,IAAIC;CACJ,IAAIC;AAEJ,SAAQ,WAAR;EACE,KAAK,QAAQ;GACX,MAAM,WAAW,eAAe,UAAU;AAC1C,OAAI,SAAS,SAAS;AACpB,aAAS,6BAA6B;AACtC,gBAAY,SAAS;AACrB;;AAGF,yCAAsC,UAAU;AAChD,oBAAiB,eAAe,WAAW,iBAAiB,CAAC,MAC1D,YAAY;AACX,QAAI,QAAQ,SAAS;AACnB,cAAS,uBAAuB;AAChC,iBAAY,QAAQ;UAEpB,SAAQ,KACN,wDACA,QAAQ,SAAS,GAClB;KAGN;AAED;;EAEF,KAAK;AACH,yCAAsC,UAAU;AAChD,oBAAiB,eAAe,WAAW,iBAAiB,CAAC,MAC1D,YAAY;AACX,QAAI,QAAQ,SAAS;AACnB,cAAS,uBAAuB;AAChC,iBAAY,QAAQ;UAEpB,SAAQ,KACN,uEACA,QAAQ,SAAS,GAClB;KAGN;AAED;EAEF,KAAK,kBAAkB;GACrB,MAAM,WAAW,eAAe,UAAU;AAC1C,OAAI,SAAS,SAAS;AACpB,aAAS,6BAA6B;AACtC,gBAAY,SAAS;AACrB;;AAGF,WAAQ,KACN,gLACD;AAED;;EAEF,KAAK,MACH;EAEF,QAEE,SAAQ,KACN,qBAAqB,KAAK,UAAU,UAAU,CAAC,uBAChD;;CAIL,MAAM,iCAAiC,WAAW,eAAe;EAC/D,AAAS,KAAK;;;;;EAMd,OAAgB,WAAW,EAAE,UAAqC;AAGhE,YACE,wBACA,KAAK,UAAU,IAAI,qBAAqB,EAAE,SAAS,CACpD;AAED,OAAI,UACF,oBAAmB,IAAI,QAAQ,UAAU;YAChC,eAET,gBACG,WAAW;AACV,QAAI,UACF,oBAAmB,IAAI,QAAQ,UAAU;KAE3C,CACD,OAAO,QAAQ;AACd,aAAS,4CAA4C,IAAI;KACzD;;EAIR,AAAS,uBACP,KACA;AACA,UAAO;IACL,GAAG;IACH,KAAK;KACH,GAAG,IAAI;KACP,QAAQ,MAAM,UAAU,WAAW,QAAQ;KAC5C;IACF;;EAGH,MAAe,YAAY,EAAE,QAAoC;AAC/D,UAAO,MAAM,CAAC,cAAc,WAAW,YAAY,CAAC;;;AAIxD,QAAO"}