Eve
Trace an Eve agent in Harbor by adding its span processor to Eve's own instrumentation setup.
Eve's spans are standard OpenTelemetry, built on the Vercel AI SDK telemetry conventions
Harbor already reads. There is no adapter package to install — Eve's registerOTel setup
takes a plain spanProcessors array, so HarborSpanProcessor plugs straight in.
Install
npm install harbor-ai-sdkregisterOTel comes from @vercel/otel, which Eve already depends on — nothing
Eve-specific to add.
Set up
import { registerOTel } from '@vercel/otel'
import { defineInstrumentation } from 'eve/instrumentation'
import { HarborSpanProcessor } from 'harbor-ai-sdk'
export default defineInstrumentation({
setup: ({ agentName }) =>
registerOTel({
serviceName: agentName,
spanProcessors: [new HarborSpanProcessor()],
}),
})That is the whole integration. setup runs once at server startup, before Eve's first
request, and agentName — passed through from defineAgent — becomes
gen_ai.agent.name in Harbor.
Don't also construct a Harbor client here. registerOTel owns the tracer provider for
the whole process, so Harbor should only ever appear in its spanProcessors array — a
separate new Harbor() would try to register a second one.
What you get
invoke_agent {agent} the turn
chat {model} a model call (step)
execute_tool {name} a tool the agent invoked
chat {model}Turn, step and tool call spans arrive as one nested trace, carrying model, provider, token usage, messages and tool arguments — the same GenAI attributes as the Vercel AI SDK integration, since Eve's telemetry is built on it.
Add the user and session
Eve tracks its own session and turn lineage internally, but doesn't expose a Harbor-shaped
user id, so capture supplies it — the same as with the
Vercel AI SDK:
import { capture } from 'harbor-ai-sdk'
const result = await capture('agent-turn', () => agent.run(input), {
userId: user.id,
sessionId: session.id,
})Reuse sessionId across turns and Harbor stitches them into one session.
HarborSpanProcessor reads HARBOR_API_KEY and HARBOR_BASE_URL from the environment, and
takes the same options explicitly if you load configuration some other way — see the
TypeScript SDK page.