Skip to main content
Eve is Vercel’s filesystem-first TypeScript framework for durable backend AI agents — you define an agent as files under an agent/ directory and Eve compiles it into an app that runs on Vercel Functions. Eve emits Vercel AI SDK OpenTelemetry spans for every turn, model call, and tool execution. Arize AX captures them by registering the @arizeai/openinference-vercel span processor in Eve’s agent/instrumentation.ts.

Prerequisites

  • Node.js 24+ (Eve’s CLI requires it)
  • An Eve agent project (npx eve@latest init my-agent)
  • An Arize AX account (sign up)
  • An AI Gateway credential for Eve’s model routing — an AI_GATEWAY_API_KEY, or a VERCEL_OIDC_TOKEN pulled with vercel link

Launch Arize AX

  1. Sign in to your Arize AX account.
  2. From Space Settings, copy your Space ID and API Key. You will set them as ARIZE_SPACE_ID and ARIZE_API_KEY below.

Install

In your Eve project, add the Arize OpenInference processor and the OpenTelemetry packages it exports through:
npm install @arizeai/openinference-vercel@^3 \
  @arizeai/openinference-semantic-conventions \
  @vercel/otel \
  @opentelemetry/api \
  @opentelemetry/exporter-trace-otlp-proto

Configure credentials

export ARIZE_SPACE_ID="<your-space-id>"
export ARIZE_API_KEY="<your-api-key>"
export AI_GATEWAY_API_KEY="<your-ai-gateway-key>"

Setup tracing

Eve auto-discovers agent/instrumentation.ts and runs it once at server startup, before any agent code. Its presence enables telemetry — there is no separate toggle, and you do not set experimental_telemetry on individual calls (Eve manages that internally). Register an OpenTelemetry provider in the setup callback, which receives the resolved agent name. The processor’s spanFilter and reparentOrphanedSpans options control which spans reach Arize and how each trace is rooted — see Span filter:
// agent/instrumentation.ts
import { defineInstrumentation } from "eve/instrumentation";
import { registerOTel } from "@vercel/otel";
import {
  isOpenInferenceSpan,
  OpenInferenceSimpleSpanProcessor,
} from "@arizeai/openinference-vercel";
import { SEMRESATTRS_PROJECT_NAME } from "@arizeai/openinference-semantic-conventions";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";

export default defineInstrumentation({
  setup: ({ agentName }) => {
    // Route to the project named by ARIZE_PROJECT_NAME (falling back to the agent
    // name), matching the ARIZE_PROJECT_NAME convention used across the Arize docs.
    const projectName = process.env.ARIZE_PROJECT_NAME ?? agentName;
    return registerOTel({
      serviceName: projectName,
      // Arize routes spans to a project by the project-name resource attribute —
      // without it the OTLP endpoint rejects spans with an InvalidArgument error.
      attributes: { [SEMRESATTRS_PROJECT_NAME]: projectName },
      spanProcessors: [
        new OpenInferenceSimpleSpanProcessor({
          exporter: new OTLPTraceExporter({
            url: "https://otlp.arize.com/v1/traces",
            headers: {
              "arize-space-id": process.env.ARIZE_SPACE_ID ?? "",
              "arize-api-key": process.env.ARIZE_API_KEY ?? "",
            },
          }),
          spanFilter: isOpenInferenceSpan,
          reparentOrphanedSpans: true,
        }),
      ],
    });
  },
});
OpenInferenceSimpleSpanProcessor exports each span synchronously as it ends, so it is safe on the short-lived serverless functions Eve runs on (no process-exit forceFlush to call). @arizeai/openinference-vercel translates the AI SDK spans into OpenInference before export.

Run Eve

Start the Eve dev server, then open a session against the built-in HTTP channel:
npm run dev
The dev server listens on http://127.0.0.1:2000 by default (pass --port to change it). Open a session against the built-in HTTP channel:
curl -X POST http://127.0.0.1:2000/eve/v1/session \
  -H 'content-type: application/json' \
  -d '{"message":"What is the weather in Brooklyn?"}'
The response returns a continuationToken in the body and an x-eve-session-id header. Stream the session’s lifecycle events to watch the turn complete:
curl http://127.0.0.1:2000/eve/v1/session/<sessionId>/stream

Expected output

{"type":"session.started","data":{"runtime":{"agentName":"weather-agent"}}}
{"type":"actions.requested","data":{"actions":[{"kind":"tool-call","toolName":"get_weather","input":{"city":"Brooklyn"}}]}}
{"type":"message.completed","data":{"message":"The weather in Brooklyn is **sunny** and **72°F**.","finishReason":"stop"}}

Verify in Arize AX

  1. Open your Arize AX space and select the project named after your agent (the project-name resource attribute above).
  2. Within ~30 seconds you should see the turn’s spans. Eve runs on the AI SDK’s GenAI-convention spans, so every span arrives named gen_ai (or gen_ai.client for the model request) rather than ai.streamText/ai.toolCall — read the OpenInference span kind to tell them apart. Each step is an agent span over a llm span; the model request is a gen_ai.client llm span (prompt, response, token usage), and each tool run is a gen_ai tool span carrying tool.name (for example get_weather). All of a turn’s steps nest under Eve’s ai.eve.turn workflow span, which reparentOrphanedSpans re-roots and tags as an agent span so it anchors the turn as a clean per-turn root.
  3. Eve attaches session context to the spans under the ai.settings.context.eve.* prefix — ai.settings.context.eve.session.id, ai.settings.context.eve.turn.id, ai.settings.context.eve.step.index, and ai.settings.context.eve.channel.kind — so you can group a trace back to its session.
  4. If no traces appear, see Troubleshooting.
Arize AX trace view of a Vercel Eve agent turn, showing the ai.eve.turn agent root span with nested agent, llm, and tool spans for each step

Check from the skill, CLI, or SDK

Confirm spans are actually reaching your Arize AX project. Use whichever fits your workflow — the skill and CLI work for any framework; the SDK check is shown for each language.
Install the Arize Skills plugin and let your coding agent check for you:
npx skills add Arize-ai/arize-skills
Then prompt your agent:
Use the arize-trace skill to export and analyze recent traces from my project. Confirm spans are arriving, and summarize any errors or latency issues.

Span filter

Two options on the processor control which spans reach Arize and how they’re rooted:
  • spanFilter: isOpenInferenceSpan keeps only the AI spans and drops the rest — the raw HTTP/fetch spans and Eve’s Vercel Workflow spans.
  • reparentOrphanedSpans: true re-roots any AI span left orphaned when the filter drops its parent, so it no longer points at a parent that was never exported. It also recognizes Eve’s ai.eve.turn wrapper as an AI-like root and tags it openinference.span.kind = AGENT, so each turn shows up as a single clean agent root with its steps nested underneath.
new OpenInferenceSimpleSpanProcessor({
  exporter,
  spanFilter: isOpenInferenceSpan,
  reparentOrphanedSpans: true, // default: false
});

Troubleshooting

  • No traces in Arize AX. Confirm the file is exactly agent/instrumentation.ts (Eve discovers it by path), and that ARIZE_SPACE_ID and ARIZE_API_KEY are set in the shell running npm run dev. Enable OpenTelemetry debug logs with export OTEL_LOG_LEVEL=debug and re-run.
  • Model auth errors. Eve routes models through AI Gateway — set AI_GATEWAY_API_KEY, or run vercel link to use a VERCEL_OIDC_TOKEN. To skip the gateway, switch the agent to a direct provider model (e.g. @ai-sdk/openai with OPENAI_API_KEY). A brand-new AI Gateway key also fails until you add a payment method — the turn errors with GatewayInternalServerError: AI Gateway requires a valid credit card on file to service requests, even if you only plan to use the free credits. Add a card in your Vercel AI Gateway dashboard to unlock them.
  • Version mismatch. Pin the OpenTelemetry packages to Eve’s @vercel/otel major: @vercel/otel@1.x requires @opentelemetry/* 1.x; @vercel/otel@2.x requires 2.x. Mismatches surface as silently missing traces.
  • gen_ai spans orphaned on the Traces tab. This happens when spanFilter: isOpenInferenceSpan drops Eve’s ai.eve.turn workflow span without re-rooting its children, leaving the per-step gen_ai spans with no parent. Set reparentOrphanedSpans: true as shown in Setup tracing for a single clean agent root per turn, and confirm @arizeai/openinference-vercel is 3.0.0 or later (the v3 major maps Eve’s v7 GenAI-convention spans and carries the ai.eve.turn reparenting fix first shipped in 2.8.1).

Resources

Cookbook: Tracing a Vercel Eve Agent

Eve Observability Docs

OpenInference Vercel Span Processor

Eve Getting Started