@langfuse/client 4.2.1 → 4.4.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.
package/dist/index.mjs CHANGED
@@ -150,7 +150,15 @@ var DatasetManager = class {
150
150
  };
151
151
 
152
152
  // src/experiment/ExperimentManager.ts
153
- import { getGlobalLogger } from "@langfuse/core";
153
+ import {
154
+ getGlobalLogger,
155
+ propagateAttributes,
156
+ serializeValue,
157
+ createExperimentId,
158
+ createExperimentItemId,
159
+ LangfuseOtelSpanAttributes,
160
+ LANGFUSE_SDK_EXPERIMENT_ENVIRONMENT
161
+ } from "@langfuse/core";
154
162
  import { startActiveObservation } from "@langfuse/tracing";
155
163
  import { ProxyTracerProvider, trace } from "@opentelemetry/api";
156
164
  var ExperimentManager = class {
@@ -380,44 +388,86 @@ var ExperimentManager = class {
380
388
  * @internal
381
389
  */
382
390
  async runItem(params) {
383
- const { item, evaluators = [], task, experimentMetadata = {} } = params;
384
- const { output, traceId, observationId } = await startActiveObservation(
385
- "experiment-item-run",
386
- async (span) => {
387
- var _a;
388
- const output2 = await task(item);
389
- span.update({
390
- input: item.input,
391
- output: output2,
392
- metadata: {
393
- experiment_name: params.experimentName,
394
- experiment_run_name: params.experimentRunName,
395
- ...experimentMetadata,
396
- ...(_a = item.metadata) != null ? _a : {},
397
- ..."id" in item && "datasetId" in item ? {
398
- dataset_id: item["datasetId"],
399
- dataset_item_id: item["id"]
400
- } : {}
401
- }
402
- });
403
- return { output: output2, traceId: span.traceId, observationId: span.id };
391
+ const { item, evaluators = [], task, experimentMetadata } = params;
392
+ const { output, traceId, observationId, datasetRunId } = await startActiveObservation("experiment-item-run", async (span) => {
393
+ const input = item.input;
394
+ const expectedOutput = item.expectedOutput;
395
+ const itemMetadata = item.metadata;
396
+ const datasetId = "datasetId" in item ? item.datasetId : void 0;
397
+ const datasetItemId = "id" in item ? item.id : void 0;
398
+ const traceId2 = span.traceId;
399
+ const observationId2 = span.id;
400
+ if (input === void 0) {
401
+ throw new Error("Experiment item is missing input. Skipping item.");
404
402
  }
405
- );
406
- let datasetRunId = void 0;
407
- if ("id" in item) {
408
- await this.langfuseClient.api.datasetRunItems.create({
409
- runName: params.experimentRunName,
410
- runDescription: params.experimentDescription,
411
- metadata: params.experimentMetadata,
412
- datasetItemId: item.id,
413
- traceId,
414
- observationId
415
- }).then((result) => {
416
- datasetRunId = result.datasetRunId;
417
- }).catch(
418
- (err) => this.logger.error("Linking dataset run item failed", err)
403
+ let datasetRunId2 = void 0;
404
+ if (datasetItemId) {
405
+ try {
406
+ const result = await this.langfuseClient.api.datasetRunItems.create(
407
+ {
408
+ runName: params.experimentRunName,
409
+ runDescription: params.experimentDescription,
410
+ metadata: params.experimentMetadata,
411
+ datasetItemId,
412
+ traceId: traceId2,
413
+ observationId: observationId2
414
+ }
415
+ );
416
+ datasetRunId2 = result.datasetRunId;
417
+ } catch (err) {
418
+ this.logger.error("Linking dataset run item failed", err);
419
+ }
420
+ }
421
+ const experimentItemId = datasetItemId || await createExperimentItemId(input);
422
+ const experimentId = datasetRunId2 || await createExperimentId();
423
+ const rootSpanAttributes = {
424
+ [LangfuseOtelSpanAttributes.ENVIRONMENT]: LANGFUSE_SDK_EXPERIMENT_ENVIRONMENT
425
+ };
426
+ if (params.experimentDescription) {
427
+ rootSpanAttributes[LangfuseOtelSpanAttributes.EXPERIMENT_DESCRIPTION] = params.experimentDescription;
428
+ }
429
+ if (expectedOutput !== void 0) {
430
+ const serialized = serializeValue(expectedOutput);
431
+ if (serialized) {
432
+ rootSpanAttributes[LangfuseOtelSpanAttributes.EXPERIMENT_ITEM_EXPECTED_OUTPUT] = serialized;
433
+ }
434
+ }
435
+ span.otelSpan.setAttributes(rootSpanAttributes);
436
+ const output2 = await propagateAttributes(
437
+ {
438
+ _internalExperiment: {
439
+ experimentId,
440
+ experimentName: params.experimentRunName,
441
+ experimentMetadata: serializeValue(experimentMetadata),
442
+ experimentDatasetId: datasetId,
443
+ experimentItemId,
444
+ experimentItemMetadata: serializeValue(itemMetadata),
445
+ experimentItemRootObservationId: span.id
446
+ }
447
+ },
448
+ async () => await task(item)
419
449
  );
420
- }
450
+ span.update({
451
+ input,
452
+ output: output2,
453
+ metadata: {
454
+ experiment_name: params.experimentName,
455
+ experiment_run_name: params.experimentRunName,
456
+ ...experimentMetadata,
457
+ ...itemMetadata != null ? itemMetadata : {},
458
+ ...datasetId && datasetItemId ? {
459
+ dataset_id: datasetId,
460
+ dataset_item_id: datasetItemId
461
+ } : {}
462
+ }
463
+ });
464
+ return {
465
+ output: output2,
466
+ traceId: traceId2,
467
+ observationId: observationId2,
468
+ datasetRunId: datasetRunId2
469
+ };
470
+ });
421
471
  const evalPromises = evaluators.map(
422
472
  async (evaluator) => {
423
473
  const params2 = {
@@ -451,6 +501,7 @@ ${JSON.stringify(params2)}
451
501
  for (const ev of evals) {
452
502
  this.langfuseClient.score.create({
453
503
  traceId,
504
+ observationId,
454
505
  ...ev
455
506
  });
456
507
  }