Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import * as Sentry from '@sentry/node';
import { defineTool } from 'eve/tools';
import { z } from 'zod';

export default defineTool({
description: 'Get the current weather for a city.',
inputSchema: z.object({ city: z.string().min(1) }),
async execute({ city }) {
return { city, condition: 'Sunny', temperatureC: 22 };
// Manual instrumentation inside a tool call: eve runs `execute` while the
// SDK's `gen_ai.execute_tool` span is active, so this user span should nest
// under it. The e2e test asserts that parent/child link.
return Sentry.startSpan(
{ name: 'resolve-weather', op: 'gen_ai.tool.manual', attributes: { 'weather.city': city } },
() => ({ city, condition: 'Sunny', temperatureC: 22 }),
);
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ test('captures Vercel AI agent spans (invoke_agent, generate_content, execute_to
const traceSpansPromise = collectStreamedSpans(
APP,
spansOfTrace =>
['gen_ai.invoke_agent', 'gen_ai.generate_content', 'gen_ai.execute_tool'].every(op =>
['gen_ai.invoke_agent', 'gen_ai.generate_content', 'gen_ai.execute_tool', 'gen_ai.tool.manual'].every(op =>
spansOfTrace.some(span => getSpanOp(span) === op),
) && spansOfTrace.some(isAgentServerSpan),
);
Comment on lines +32 to 35

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The test may hang indefinitely if the 'gen_ai.tool.manual' span is not emitted, as the completion predicate in collectStreamedSpans will never resolve.
Severity: MEDIUM

Suggested Fix

Add a timeout to the collectStreamedSpans utility or the specific test case. This will ensure the test fails quickly with a clear error message if the required spans are not received within a reasonable time, rather than hanging.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: dev-packages/e2e-tests/test-applications/node-eve/tests/eve.test.ts#L32-L35

Potential issue: The test's completion predicate in `collectStreamedSpans` now requires
the presence of a `'gen_ai.tool.manual'` span. The underlying `waitForStreamedSpans`
function has no built-in timeout. If the `'gen_ai.tool.manual'` span is not emitted for
any reason (e.g., a flushing or context issue), the predicate will never be satisfied.
This causes the test to hang until the outer Playwright timeout is reached, masking the
specific failure (the missing span) with a generic timeout error.

Did we get this right? πŸ‘ / πŸ‘Ž to inform future reviews.

Expand Down Expand Up @@ -66,6 +66,16 @@ test('captures Vercel AI agent spans (invoke_agent, generate_content, execute_to
// The tool returns `{ city, condition: 'Sunny', temperatureC: 22 }`.
expect(executeTool?.attributes?.['gen_ai.tool.call.result']?.value).toContain('Sunny');

// `get_weather` wraps its work in a manual `Sentry.startSpan`. Because eve runs
// the tool while the SDK's `execute_tool` span is active, that user span nests
// directly under it β€” this is the manual-instrumentation-inside-a-tool case.
const manualSpan = traceSpans.find(span => getSpanOp(span) === 'gen_ai.tool.manual');
expect(manualSpan?.name).toBe('resolve-weather');
expect(manualSpan?.attributes?.['weather.city']?.value).toBe('Paris');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The test assertion toBe('Paris') for the LLM-derived weather.city is too strict and will cause flakiness, as LLM output is non-deterministic.
Severity: MEDIUM

Suggested Fix

Change the assertion from expect(weather.city).toBe('Paris') to expect(weather.city).toContain('Paris'). This makes the test more robust against non-deterministic LLM output variations, consistent with the existing test on line 64.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: dev-packages/e2e-tests/test-applications/node-eve/tests/eve.test.ts#L74

Potential issue: The test at line 74 asserts that the LLM-derived `weather.city`
attribute is exactly `'Paris'`. However, LLM output is non-deterministic and may produce
variations like `'paris'` or `'Paris, France'`. This strict `toBe('Paris')` assertion
introduces flakiness, as it will fail on valid but differently formatted outputs. A
similar, pre-existing assertion on line 64 correctly uses `toContain('Paris')` to handle
this variability, indicating the new assertion is overly strict.

Did we get this right? πŸ‘ / πŸ‘Ž to inform future reviews.

expect(manualSpan?.is_segment).toBe(false);
expect(manualSpan?.trace_id).toBe(executeTool?.trace_id);
expect(manualSpan?.parent_span_id).toBe(executeTool?.span_id);

// `agent/hooks/sentry.ts` sets the eve session id as the conversation id via
// `Sentry.eveConversationHook()`, so every gen_ai span in the turn is tagged with it β€” that is
// what links a multi-turn session (each turn is its own trace) into one Sentry conversation.
Expand Down
Loading