lelangfuse-eve

Trace integration

Send Eve traces to Langfuse with prompt attribution, session grouping, and Gateway metadata.

The Quick start uses two provider files: one enables complete trace content and one sends Eve's native trace model to Langfuse.

agent/instrumentation/otel.ts
import { otel } from "eve/instrumentation/otel";

export default otel({
  tracePolicy: () => ({
    emit: true,
    recordInputs: true,
    recordOutputs: true,
  }),
});
agent/instrumentation/langfuse.ts
import { defineLangfuseInstrumentation } from "@vantezzen/langfuse-eve/instrumentation";

export default defineLangfuseInstrumentation();

The root agent must enable experimental.instrumentationProviders in agent/agent.ts. No shared instrumentation.ts file or manual OpenTelemetry registration is needed.

What appears in Langfuse

The integration maps Eve data into Langfuse fields that can be searched and filtered:

Eve activityLangfuse result
Model callGeneration with model, tokens, latency, and usage
Langfuse-backed instructionsPrompt name and version on the generation
Root agent or declared subagentAgent observation with parent lineage
Tool or skill actionTool observation
Step and workflowChain observation
Memory lookupRetriever observation
Vercel AI Gateway responseGeneration ID and cost metadata

Every root and child session keeps its own prompt attribution. Child spans include their parent call, session, and turn IDs, while Langfuse groups the conversation under the root Eve session by default.

Langfuse fieldDefault value
session.idRoot Eve session ID
user.idInitiating principal ID, when available
Trace metadataRoot/local session, turn, step, channel, and parent lineage
Observation promptCurrent agent's selected non-fallback prompt
Prompt trace metadataAll Langfuse prompts resolved for the current agent

Add product context

Use context to add fields your team filters by in Langfuse:

agent/instrumentation/langfuse.ts
import { defineLangfuseInstrumentation } from "@vantezzen/langfuse-eve/instrumentation";

export default defineLangfuseInstrumentation({
  context: ({ channel, session }) => ({
    metadata: {
      channel: channel.kind,
      plan: session.auth.current?.attributes.plan?.toString() ?? "unknown",
      workspaceId:
        session.auth.current?.attributes.workspaceId?.toString() ?? "unknown",
    },
    tags: ["support", process.env.VERCEL_ENV ?? "development"],
    traceName: "support-agent",
  }),
});

Return null for userId or sessionId to suppress the inferred value. Set a custom sessionId when your product already has a durable conversation identifier.

Control captured content

Eve's default OpenTelemetry policy records inputs and outputs for public conversations and for development. Non-public conversations outside development emit trace metadata but omit model and tool content.

The Quick start overrides that default so Langfuse traces include model and tool content:

agent/instrumentation/otel.ts
import { otel } from "eve/instrumentation/otel";

export default otel({
  tracePolicy: () => ({
    emit: true,
    recordInputs: true,
    recordOutputs: true,
  }),
});

Review this policy before deployment

Inputs can contain prompts, user messages, documents, and tool arguments. Outputs can contain model responses, reasoning, tool results, and error details.

Restrict the policy when only public or development conversations may send content:

agent/instrumentation/otel.ts
import { otel } from "eve/instrumentation/otel";

export default otel({
  tracePolicy: ({ audience, environment }) => ({
    emit: true,
    recordInputs: audience === "public" || environment === "development",
    recordOutputs: audience === "public" || environment === "development",
  }),
});

Remove otel.ts entirely to use Eve's default capture policy. You can also use the file to set process-wide OpenTelemetry resource, sampler, or propagator options.

The otel() policy is shared by every OpenTelemetry destination. A destination cannot restore content removed by that policy.

Configure Langfuse export

Pass official LangfuseSpanProcessor options through langfuse:

agent/instrumentation/langfuse.ts
export default defineLangfuseInstrumentation({
  langfuse: {
    environment: process.env.VERCEL_ENV ?? "development",
    release: process.env.VERCEL_GIT_COMMIT_SHA,
    mask: ({ data }) => redactSecrets(data),
  },
});

shouldExportSpan replaces the default filter. If you provide it, include the Eve spans you want Langfuse to receive.

Add Langfuse-only span fields

enrichSpan adds attributes to the copy sent to Langfuse. Other destinations still receive the original span.

agent/instrumentation/langfuse.ts
export default defineLangfuseInstrumentation({
  enrichSpan: (span) => ({
    "langfuse.observation.metadata.billing_region":
      regionFor(span.attributes["cloud.region"]),
  }),
});

Add another trace destination

Add another file beside langfuse.ts. Eve owns the shared OpenTelemetry pipeline and loads each destination independently, so no composition helper is required.

langfuse.ts
sentry.ts
otel.ts

On this page