Add custom telemetry exporter support (#1602)

* WIP langsmith & AI SDK integration

* Add changeset

* Add exporter support to deployed tasks

* Better support for external exporters and group exporters and instrumentations under the telemetry config property

* Missing changes
This commit is contained in:
Eric Allam
2025-01-13 22:43:34 +00:00
committed by GitHub
parent 14ce599218
commit b3aa87ee26
12 changed files with 266 additions and 12 deletions
+6
View File
@@ -0,0 +1,6 @@
---
"trigger.dev": patch
"@trigger.dev/core": patch
---
Add otel exporter support
+4 -2
View File
@@ -317,8 +317,10 @@ function adaptResolveEnvVarsToSyncEnvVarsExtension(
function getInstrumentedPackageNames(config: ResolvedConfig): Array<string> {
const packageNames = [];
if (config.instrumentations) {
for (const instrumentation of config.instrumentations) {
if (config.instrumentations ?? config.telemetry?.instrumentations) {
for (const instrumentation of config.telemetry?.instrumentations ??
config.instrumentations ??
[]) {
const moduleDefinitions = (
instrumentation as any
).getModuleDefinitions?.() as Array<InstrumentationModuleDefinition>;
@@ -148,7 +148,8 @@ async function bootstrap() {
const tracingSDK = new TracingSDK({
url: env.OTEL_EXPORTER_OTLP_ENDPOINT ?? "http://0.0.0.0:4318",
instrumentations: config.instrumentations ?? [],
instrumentations: config.telemetry?.instrumentations ?? config.instrumentations ?? [],
exporters: config.telemetry?.exporters ?? [],
diagLogLevel: (env.OTEL_LOG_LEVEL as TracingDiagnosticLogLevel) ?? "none",
forceFlushTimeoutMillis: 30_000,
});
@@ -128,7 +128,8 @@ async function bootstrap() {
const tracingSDK = new TracingSDK({
url: env.OTEL_EXPORTER_OTLP_ENDPOINT ?? "http://0.0.0.0:4318",
instrumentations: config.instrumentations ?? [],
instrumentations: config.telemetry?.instrumentations ?? config.instrumentations ?? [],
exporters: config.telemetry?.exporters ?? [],
diagLogLevel: (env.OTEL_LOG_LEVEL as TracingDiagnosticLogLevel) ?? "none",
forceFlushTimeoutMillis: 30_000,
});
+19
View File
@@ -1,4 +1,5 @@
import type { Instrumentation } from "@opentelemetry/instrumentation";
import type { SpanExporter } from "@opentelemetry/sdk-trace-base";
import type { BuildExtension } from "./build/extensions.js";
import type { MachinePresetName } from "./schemas/common.js";
import type { LogLevel } from "./logger/taskLogger.js";
@@ -53,9 +54,27 @@ export type TriggerConfig = {
* Instrumentations to use for OpenTelemetry. This is useful if you want to add custom instrumentations to your tasks.
*
* @see https://trigger.dev/docs/config/config-file#instrumentations
*
* @deprecated Use the `telemetry.instrumentations` option instead.
*/
instrumentations?: Array<Instrumentation>;
telemetry?: {
/**
* Instrumentations to use for OpenTelemetry. This is useful if you want to add custom instrumentations to your tasks.
*
* @see https://trigger.dev/docs/config/config-file#instrumentations
*/
instrumentations?: Array<Instrumentation>;
/**
* Exporters to use for OpenTelemetry. This is useful if you want to add custom exporters to your tasks.
*
* @see https://trigger.dev/docs/config/config-file#exporters
*/
exporters?: Array<SpanExporter>;
};
/**
* Specify a custom path to your tsconfig file. This is useful if you have a custom tsconfig file that you want to use.
*/
+69
View File
@@ -20,6 +20,7 @@ import {
import {
BatchSpanProcessor,
NodeTracerProvider,
ReadableSpan,
SimpleSpanProcessor,
SpanExporter,
} from "@opentelemetry/sdk-trace-node";
@@ -85,6 +86,7 @@ export type TracingSDKConfig = {
forceFlushTimeoutMillis?: number;
resource?: IResource;
instrumentations?: Instrumentation[];
exporters?: SpanExporter[];
diagLogLevel?: TracingDiagnosticLogLevel;
};
@@ -111,6 +113,8 @@ export class TracingSDK {
.merge(
new Resource({
[SemanticResourceAttributes.CLOUD_PROVIDER]: "trigger.dev",
[SemanticResourceAttributes.SERVICE_NAME]:
getEnvVar("OTEL_SERVICE_NAME") ?? "trigger.dev",
[SemanticInternalAttributes.TRIGGER]: true,
[SemanticInternalAttributes.CLI_VERSION]: VERSION,
})
@@ -153,6 +157,25 @@ export class TracingSDK {
)
);
const externalTraceId = crypto.randomUUID();
for (const exporter of config.exporters ?? []) {
traceProvider.addSpanProcessor(
getEnvVar("OTEL_BATCH_PROCESSING_ENABLED") === "1"
? new BatchSpanProcessor(new ExternalSpanExporterWrapper(exporter, externalTraceId), {
maxExportBatchSize: parseInt(getEnvVar("OTEL_SPAN_MAX_EXPORT_BATCH_SIZE") ?? "64"),
scheduledDelayMillis: parseInt(
getEnvVar("OTEL_SPAN_SCHEDULED_DELAY_MILLIS") ?? "200"
),
exportTimeoutMillis: parseInt(
getEnvVar("OTEL_SPAN_EXPORT_TIMEOUT_MILLIS") ?? "30000"
),
maxQueueSize: parseInt(getEnvVar("OTEL_SPAN_MAX_QUEUE_SIZE") ?? "512"),
})
: new SimpleSpanProcessor(new ExternalSpanExporterWrapper(exporter, externalTraceId))
);
}
traceProvider.register();
registerInstrumentations({
@@ -236,3 +259,49 @@ function setLogLevel(level: TracingDiagnosticLogLevel) {
diag.setLogger(new DiagConsoleLogger(), diagLogLevel);
}
class ExternalSpanExporterWrapper {
constructor(
private underlyingExporter: SpanExporter,
private externalTraceId: string
) {}
private transformSpan(span: ReadableSpan): ReadableSpan | undefined {
if (span.attributes[SemanticInternalAttributes.SPAN_PARTIAL]) {
// Skip partial spans
return;
}
const spanContext = span.spanContext();
return {
...span,
spanContext: () => ({ ...spanContext, traceId: this.externalTraceId }),
parentSpanId: span.attributes[SemanticInternalAttributes.SPAN_ATTEMPT]
? undefined
: span.parentSpanId,
};
}
export(spans: any[], resultCallback: (result: any) => void): void {
try {
const modifiedSpans = spans.map(this.transformSpan.bind(this));
this.underlyingExporter.export(
modifiedSpans.filter(Boolean) as ReadableSpan[],
resultCallback
);
} catch (e) {
console.error(e);
}
}
shutdown(): Promise<void> {
return this.underlyingExporter.shutdown();
}
forceFlush?(): Promise<void> {
return this.underlyingExporter.forceFlush
? this.underlyingExporter.forceFlush()
: Promise.resolve();
}
}
@@ -51,4 +51,5 @@ export const SemanticInternalAttributes = {
RATE_LIMIT_LIMIT: "response.rateLimit.limit",
RATE_LIMIT_REMAINING: "response.rateLimit.remaining",
RATE_LIMIT_RESET: "response.rateLimit.reset",
SPAN_ATTEMPT: "$span.attempt",
};
@@ -231,6 +231,7 @@ export class TaskExecutor {
kind: SpanKind.CONSUMER,
attributes: {
[SemanticInternalAttributes.STYLE_ICON]: "attempt",
[SemanticInternalAttributes.SPAN_ATTEMPT]: true,
},
},
this._tracer.extractContext(traceContext),
+146 -4
View File
@@ -1628,6 +1628,9 @@ importers:
'@fast-csv/parse':
specifier: ^5.0.2
version: 5.0.2
'@opentelemetry/exporter-trace-otlp-http':
specifier: ^0.57.0
version: 0.57.0(@opentelemetry/api@1.9.0)
'@radix-ui/react-dialog':
specifier: ^1.0.3
version: 1.0.4(@types/react-dom@18.2.7)(@types/react@18.3.1)(react-dom@18.2.0)(react@18.3.1)
@@ -1667,12 +1670,15 @@ importers:
date-fns:
specifier: ^4.1.0
version: 4.1.0
langsmith:
specifier: ^0.2.15
version: 0.2.15(openai@4.68.4)
lucide-react:
specifier: ^0.451.0
version: 0.451.0(react@18.3.1)
next:
specifier: 14.2.15
version: 14.2.15(@playwright/test@1.37.0)(react-dom@18.2.0)(react@18.3.1)
version: 14.2.15(@opentelemetry/api@1.9.0)(@playwright/test@1.37.0)(react-dom@18.2.0)(react@18.3.1)
openai:
specifier: ^4.68.4
version: 4.68.4(zod@3.23.8)
@@ -8210,6 +8216,13 @@ packages:
dependencies:
'@opentelemetry/api': 1.9.0
/@opentelemetry/api-logs@0.57.0:
resolution: {integrity: sha512-l1aJ30CXeauVYaI+btiynHpw341LthkMTv3omi1VJDX14werY2Wmv9n1yudMsq9HuY0m8PvXEVX4d8zxEb+WRg==}
engines: {node: '>=14'}
dependencies:
'@opentelemetry/api': 1.9.0
dev: false
/@opentelemetry/api@1.4.1:
resolution: {integrity: sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==}
engines: {node: '>=8.0.0'}
@@ -8289,6 +8302,16 @@ packages:
'@opentelemetry/semantic-conventions': 1.25.1
dev: false
/@opentelemetry/core@1.30.0(@opentelemetry/api@1.9.0):
resolution: {integrity: sha512-Q/3u/K73KUjTCnFUP97ZY+pBjQ1kPEgjOfXj/bJl8zW7GbXdkw6cwuyZk6ZTXkVgCBsYRYUzx4fvYK1jxdb9MA==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/semantic-conventions': 1.28.0
dev: false
/@opentelemetry/exporter-logs-otlp-http@0.49.1(@opentelemetry/api@1.4.1):
resolution: {integrity: sha512-3QoBnIGCmEkujynUP0mK155QtOM0MSf9FNrEw7u9ieCFsoMiyatg2hPp+alEDONJ8N8wGEK+wP2q3icgXBiggw==}
engines: {node: '>=14'}
@@ -8375,6 +8398,20 @@ packages:
'@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0)
dev: false
/@opentelemetry/exporter-trace-otlp-http@0.57.0(@opentelemetry/api@1.9.0):
resolution: {integrity: sha512-BJl35PSkwoMlGEOrzjCG1ih6zqZoAZJIR4xyqSKC2BqPtwuRjID0vWBaEdP9xrxxJTEIEQw+gEY/0pUgicX0ew==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0)
'@opentelemetry/otlp-exporter-base': 0.57.0(@opentelemetry/api@1.9.0)
'@opentelemetry/otlp-transformer': 0.57.0(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.30.0(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 1.30.0(@opentelemetry/api@1.9.0)
dev: false
/@opentelemetry/exporter-trace-otlp-proto@0.49.1(@opentelemetry/api@1.4.1):
resolution: {integrity: sha512-n8ON/c9pdMyYAfSFWKkgsPwjYoxnki+6Olzo+klKfW7KqLWoyEkryNkbcMIYnGGNXwdkMIrjoaP0VxXB26Oxcg==}
engines: {node: '>=14'}
@@ -8654,6 +8691,17 @@ packages:
'@opentelemetry/otlp-transformer': 0.52.1(@opentelemetry/api@1.9.0)
dev: false
/@opentelemetry/otlp-exporter-base@0.57.0(@opentelemetry/api@1.9.0):
resolution: {integrity: sha512-QQl4Ngm3D6H8SDO0EM642ncTxjRsf/HDq7+IWIA0eaEK/NTsJeQ3iYJiZj3F4jkALnvyeM1kkwd+DHtqxTBx9Q==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0)
'@opentelemetry/otlp-transformer': 0.57.0(@opentelemetry/api@1.9.0)
dev: false
/@opentelemetry/otlp-grpc-exporter-base@0.49.1(@opentelemetry/api@1.4.1):
resolution: {integrity: sha512-DNDNUWmOqtKTFJAyOyHHKotVox0NQ/09ETX8fUOeEtyNVHoGekAVtBbvIA3AtK+JflP7LC0PTjlLfruPM3Wy6w==}
engines: {node: '>=14'}
@@ -8723,6 +8771,22 @@ packages:
protobufjs: 7.3.2
dev: false
/@opentelemetry/otlp-transformer@0.57.0(@opentelemetry/api@1.9.0):
resolution: {integrity: sha512-yHX7sdwkdAmSa6Jbi3caSLDWy0PCHS1pKQeKz8AIWSyQqL7IojHKgdk9A+7eRd98Z1n9YTdwWSWLnObvIqhEhQ==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': ^1.3.0
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/api-logs': 0.57.0
'@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.30.0(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-logs': 0.57.0(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-metrics': 1.30.0(@opentelemetry/api@1.9.0)
'@opentelemetry/sdk-trace-base': 1.30.0(@opentelemetry/api@1.9.0)
protobufjs: 7.3.2
dev: false
/@opentelemetry/propagator-b3@1.22.0(@opentelemetry/api@1.4.1):
resolution: {integrity: sha512-qBItJm9ygg/jCB5rmivyGz1qmKZPsL/sX715JqPMFgq++Idm0x+N9sLQvWFHFt2+ZINnCSojw7FVBgFW6izcXA==}
engines: {node: '>=14'}
@@ -8827,6 +8891,17 @@ packages:
'@opentelemetry/semantic-conventions': 1.25.1
dev: false
/@opentelemetry/resources@1.30.0(@opentelemetry/api@1.9.0):
resolution: {integrity: sha512-5mGMjL0Uld/99t7/pcd7CuVtJbkARckLVuiOX84nO8RtLtIz0/J6EOHM2TGvPZ6F4K+XjUq13gMx14w80SVCQg==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.28.0
dev: false
/@opentelemetry/sdk-logs@0.49.1(@opentelemetry/api-logs@0.49.1)(@opentelemetry/api@1.4.1):
resolution: {integrity: sha512-gCzYWsJE0h+3cuh3/cK+9UwlVFyHvj3PReIOCDOmdeXOp90ZjKRoDOJBc3mvk1LL6wyl1RWIivR8Rg9OToyesw==}
engines: {node: '>=14'}
@@ -8865,6 +8940,18 @@ packages:
'@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0)
dev: false
/@opentelemetry/sdk-logs@0.57.0(@opentelemetry/api@1.9.0):
resolution: {integrity: sha512-6Kbxdu/QE9LWH7+WSLmYo3DjAq+c55TiCLXiXu6b/2m2muy5SyOG2m0MrGqetyRpfYSSbIqHmJoqNVTN3+2a9g==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.4.0 <1.10.0'
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/api-logs': 0.57.0
'@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.30.0(@opentelemetry/api@1.9.0)
dev: false
/@opentelemetry/sdk-metrics@1.22.0(@opentelemetry/api@1.4.1):
resolution: {integrity: sha512-k6iIx6H3TZ+BVMr2z8M16ri2OxWaljg5h8ihGJxi/KQWcjign6FEaEzuigXt5bK9wVEhqAcWLCfarSftaNWkkg==}
engines: {node: '>=14'}
@@ -8889,6 +8976,17 @@ packages:
lodash.merge: 4.6.2
dev: false
/@opentelemetry/sdk-metrics@1.30.0(@opentelemetry/api@1.9.0):
resolution: {integrity: sha512-5kcj6APyRMvv6dEIP5plz2qfJAD4OMipBRT11u/pa1a68rHKI2Ln+iXVkAGKgx8o7CXbD7FdPypTUY88ZQgP4Q==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.3.0 <1.10.0'
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.30.0(@opentelemetry/api@1.9.0)
dev: false
/@opentelemetry/sdk-node@0.49.1(@opentelemetry/api@1.4.1):
resolution: {integrity: sha512-feBIT85ndiSHXsQ2gfGpXC/sNeX4GCHLksC4A9s/bfpUbbgbCSl0RvzZlmEpCHarNrkZMwFRi4H0xFfgvJEjrg==}
engines: {node: '>=14'}
@@ -8985,6 +9083,18 @@ packages:
'@opentelemetry/semantic-conventions': 1.25.1
dev: false
/@opentelemetry/sdk-trace-base@1.30.0(@opentelemetry/api@1.9.0):
resolution: {integrity: sha512-RKQDaDIkV7PwizmHw+rE/FgfB2a6MBx+AEVVlAHXRG1YYxLiBpPX2KhmoB99R5vA4b72iJrjle68NDWnbrE9Dg==}
engines: {node: '>=14'}
peerDependencies:
'@opentelemetry/api': '>=1.0.0 <1.10.0'
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0)
'@opentelemetry/resources': 1.30.0(@opentelemetry/api@1.9.0)
'@opentelemetry/semantic-conventions': 1.28.0
dev: false
/@opentelemetry/sdk-trace-node@1.22.0(@opentelemetry/api@1.4.1):
resolution: {integrity: sha512-gTGquNz7ue8uMeiWPwp3CU321OstQ84r7PCDtOaCicjbJxzvO8RZMlEC4geOipTeiF88kss5n6w+//A0MhP1lQ==}
engines: {node: '>=14'}
@@ -9067,6 +9177,11 @@ packages:
engines: {node: '>=14'}
dev: false
/@opentelemetry/semantic-conventions@1.28.0:
resolution: {integrity: sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==}
engines: {node: '>=14'}
dev: false
/@pkgjs/parseargs@0.11.0:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
@@ -16938,6 +17053,10 @@ packages:
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
dev: true
/@types/uuid@10.0.0:
resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==}
dev: false
/@types/uuid@9.0.0:
resolution: {integrity: sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q==}
dev: true
@@ -17214,7 +17333,7 @@ packages:
dependencies:
'@uploadthing/shared': 7.0.3
file-selector: 0.6.0
next: 14.2.15(@playwright/test@1.37.0)(react-dom@18.2.0)(react@18.3.1)
next: 14.2.15(@opentelemetry/api@1.9.0)(@playwright/test@1.37.0)(react-dom@18.2.0)(react@18.3.1)
react: 18.3.1
uploadthing: 7.1.0(next@14.2.15)(tailwindcss@3.4.1)
dev: false
@@ -24007,6 +24126,23 @@ packages:
engines: {node: '>=14.0.0'}
dev: false
/langsmith@0.2.15(openai@4.68.4):
resolution: {integrity: sha512-homtJU41iitqIZVuuLW7iarCzD4f39KcfP9RTBWav9jifhrsDa1Ez89Ejr+4qi72iuBu8Y5xykchsGVgiEZ93w==}
peerDependencies:
openai: '*'
peerDependenciesMeta:
openai:
optional: true
dependencies:
'@types/uuid': 10.0.0
commander: 10.0.1
openai: 4.68.4(zod@3.23.8)
p-queue: 6.6.2
p-retry: 4.6.2
semver: 7.6.3
uuid: 10.0.0
dev: false
/language-subtag-registry@0.3.22:
resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==}
dev: true
@@ -25369,7 +25505,7 @@ packages:
- babel-plugin-macros
dev: false
/next@14.2.15(@playwright/test@1.37.0)(react-dom@18.2.0)(react@18.3.1):
/next@14.2.15(@opentelemetry/api@1.9.0)(@playwright/test@1.37.0)(react-dom@18.2.0)(react@18.3.1):
resolution: {integrity: sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw==}
engines: {node: '>=18.17.0'}
hasBin: true
@@ -25388,6 +25524,7 @@ packages:
optional: true
dependencies:
'@next/env': 14.2.15
'@opentelemetry/api': 1.9.0
'@playwright/test': 1.37.0
'@swc/helpers': 0.5.5
busboy: 1.6.0
@@ -31242,7 +31379,7 @@ packages:
'@uploadthing/mime-types': 0.3.0
'@uploadthing/shared': 7.0.3
effect: 3.7.2
next: 14.2.15(@playwright/test@1.37.0)(react-dom@18.2.0)(react@18.3.1)
next: 14.2.15(@opentelemetry/api@1.9.0)(@playwright/test@1.37.0)(react-dom@18.2.0)(react@18.3.1)
tailwindcss: 3.4.1(ts-node@10.9.1)
dev: false
@@ -31387,6 +31524,11 @@ packages:
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
engines: {node: '>= 0.4.0'}
/uuid@10.0.0:
resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==}
hasBin: true
dev: false
/uuid@3.4.0:
resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==}
deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
+2
View File
@@ -14,6 +14,7 @@
"@ai-sdk/openai": "^1.0.1",
"@fal-ai/serverless-client": "^0.15.0",
"@fast-csv/parse": "^5.0.2",
"@opentelemetry/exporter-trace-otlp-http": "^0.57.0",
"@radix-ui/react-dialog": "^1.0.3",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-progress": "^1.1.1",
@@ -27,6 +28,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
"langsmith": "^0.2.15",
"lucide-react": "^0.451.0",
"next": "14.2.15",
"openai": "^4.68.4",
+10 -4
View File
@@ -4,6 +4,7 @@ import { streamText, type TextStreamPart } from "ai";
import { setTimeout } from "node:timers/promises";
import { z } from "zod";
import OpenAI from "openai";
import { AISDKExporter } from "langsmith/vercel";
const openaiSDK = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
@@ -98,16 +99,21 @@ export const openaiStreaming = schemaTask({
run: async ({ model, prompt }) => {
logger.info("Running OpenAI model", { model, prompt });
const telemetrySettings = AISDKExporter.getSettings();
logger.info("Telemetry settings", { telemetrySettings });
const result = streamText({
model: openai(model),
prompt,
tools: {
getWeather: weatherTask.tool,
},
maxSteps: 10,
experimental_telemetry: telemetrySettings,
});
const stream = await metadata.stream("openai", result.fullStream);
for await (const chunk of stream) {
logger.log("Received chunk", { chunk });
}
},
});
@@ -1,9 +1,13 @@
import { defineConfig } from "@trigger.dev/sdk/v3";
import { rscExtension } from "@trigger.dev/rsc";
import { AISDKExporter } from "langsmith/vercel";
export default defineConfig({
project: "proj_bzhdaqhlymtuhlrcgbqy",
dirs: ["./src/trigger"],
telemetry: {
exporters: [new AISDKExporter()],
},
build: {
extensions: [rscExtension({ reactDomEnvironment: "worker" })],
},