-
Notifications
You must be signed in to change notification settings - Fork 46
fix(ai-sdk): add agent detection support for AI SDK #830
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Adds automatic agent detection when using Vercel AI SDK with agent metadata,
following the Python OpenLLMetry reference implementation.
**Changes:**
- Enhanced `transformTelemetryMetadata()` to detect `agent` metadata key
- Auto-sets `gen_ai.agent.name` and `traceloop.span.kind: "agent"` when detected
- Preserves all metadata as `traceloop.association.properties.*`
- Added 2 comprehensive tests for agent detection
- Added 2 sample agent applications demonstrating usage
**Example Usage:**
```typescript
await generateText({
model: openai("gpt-4o"),
messages: [...],
experimental_telemetry: {
isEnabled: true,
metadata: {
agent: "research_assistant",
sessionId: "session_123",
},
},
});
```
**Resulting Attributes:**
- `gen_ai.agent.name`: "research_assistant"
- `traceloop.span.kind`: "agent"
- `traceloop.association.properties.agent`: "research_assistant"
- `traceloop.association.properties.sessionId`: "session_123"
All tests passing (5/5 agent tests).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughAdds two sample Vercel AI agents and npm scripts; implements span-name propagation, agent-name and tool-span attribute handling in tracing transforms; stores and propagates agent names per-trace in the span processor; and adds tests plus a HAR recording validating agent/tool behaviors. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User
participant ResearchAgent
participant Traceloop as traceloop.withWorkflow
participant LLM as generateText (GPT-4o)
participant Tools as Tools (search/analyze/report)
participant Memory as AgentMemory
User->>ResearchAgent: demonstrateAgent(userId)
ResearchAgent->>ResearchAgent: init session & history
ResearchAgent->>Traceloop: withWorkflow(telemetry)
Traceloop->>LLM: generateText(prompt, tools, metadata)
LLM->>Tools: call analyzeTrends
Tools->>Memory: save analysis
Memory-->>Tools: stored result
Tools-->>LLM: tool result
LLM-->>Traceloop: assistant response
Traceloop-->>ResearchAgent: response (added to history)
ResearchAgent-->>User: reply + metadata
sequenceDiagram
autonumber
participant main
participant SimpleAgent as runSimpleAgent
participant Traceloop as traceloop.withWorkflow
participant LLM as generateText (GPT-4o)
participant Tools as Tools (calculator, tasks)
participant Storage as InMemoryStorage
main->>SimpleAgent: start
SimpleAgent->>Traceloop: withWorkflow(session metadata)
Traceloop->>LLM: generateText(prompt, tools)
LLM->>Tools: execute calculate/add
Tools->>Storage: log calculation
Storage-->>Tools: result
Tools-->>LLM: calculation result
LLM->>Tools: execute createTask
Tools->>Storage: create task
Storage-->>Tools: task id
LLM-->>Traceloop: final response
Traceloop-->>SimpleAgent: response
SimpleAgent-->>main: done (report stats)
sequenceDiagram
autonumber
participant Span
participant transformAiSdk as transformAiSdkSpanAttributes
participant transformLLM as transformLLMSpans
participant transformTelemetry as transformTelemetryMetadata
participant Output
Span->>transformAiSdk: span(name, attrs)
transformAiSdk->>transformLLM: transformLLMSpans(attrs, span.name)
transformLLM->>transformTelemetry: transformTelemetryMetadata(attrs, span.name)
alt ai.telemetry.metadata.agent present
transformTelemetry->>Output: set GEN_AI_AGENT_NAME
alt root AI span (run.ai)
transformTelemetry->>Output: set TRACELOOP_SPAN_KIND = "agent" & TRACELOOP_ENTITY_NAME
end
end
alt ai.toolCall present
transformLLM->>Output: set TRACELOOP_SPAN_KIND = "tool", TRACELOOP_ENTITY_NAME from tool, set TRACELOOP_ENTITY_INPUT/OUTPUT, remove ai.toolCall.args/result
end
transformLLM-->>transformAiSdk: enhanced attrs
transformAiSdk-->>Span: apply attrs
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Important
Looks good to me! 👍
Reviewed everything up to e4790d0 in 2 minutes and 7 seconds. Click for details.
- Reviewed
671lines of code in5files - Skipped
0files when reviewing. - Skipped posting
3draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:368
- Draft comment:
The variablemetadataAttributesis populated but never used later. Consider removing it unless you plan to use it in future enhancements. - Reason this comment was not posted:
Comment was on unchanged code.
2. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:398
- Draft comment:
Good integration for agent detection. As an optional improvement, consider handling empty or whitespace-only 'agent' values (e.g., trim the value before setting agent attributes). - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 15% vs. threshold = 50% This comment is phrased as "As an optional improvement, consider..." which is a soft suggestion rather than identifying a clear bug or issue. The rules state that comments should not be speculative and should clearly require a code change. This is explicitly marked as "optional" by the commenter. While handling empty/whitespace values could be a valid improvement, the comment doesn't demonstrate that this is actually a problem in practice - it's just a "nice to have" suggestion. The code change is adding new functionality for agent detection, and the comment is suggesting additional validation that wasn't part of the original change scope. The comment could be valid if empty or whitespace-only agent names would cause actual problems downstream. Without seeing how GEN_AI_AGENT_NAME is used elsewhere, I can't be certain this isn't a real issue. Maybe empty agent names break something? Even if empty agent names could theoretically cause issues, the comment is explicitly framed as "optional" and uses "consider" language, which violates the rule about making clear, actionable comments. If this were a real issue, it should be stated definitively. The burden of proof is on keeping the comment, and "optional improvement" suggestions should be deleted. This comment should be deleted. It's explicitly marked as "optional" and uses tentative language ("consider"), which doesn't meet the bar for actionable review comments. The rules state comments should clearly require a code change, not suggest optional improvements.
3. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:405
- Draft comment:
The comment about context propagation is helpful. Ensure that users are aware that metadata should be set in context before span creation if child spans need to inherit it. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%This comment is asking the PR author to ensure that users are aware of a specific behavior, which is not allowed according to the rules. It doesn't provide a specific code suggestion or ask for a test to be written. It seems to be more of a reminder or a guideline rather than a specific actionable comment.
Workflow ID: wflow_6cpovWRRyfEGSkwq
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
Updated agent detection to only set `traceloop.span.kind: "agent"` on the root AI span (ai.generateText / run.ai), not on child spans like text.generate or tool calls. Changes: - Pass span name through transformation chain - Only set span kind when span name is "ai.generateText" - Still set `gen_ai.agent.name` on all spans for context - Added test to verify child spans don't get marked as agent All 6 agent tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (3)
packages/traceloop-sdk/test/ai-sdk-transformations.test.ts (1)
1749-1824: Agent metadata tests align well with new transformLLMSpans behaviorThe three new tests correctly exercise:
- Root span behavior:
ai.generateTextsetsGEN_AI_AGENT_NAME,TRACELOOP_SPAN_KIND = "agent", and association properties.- Child span behavior:
ai.generateText.doGeneratesetsGEN_AI_AGENT_NAMEbut notTRACELOOP_SPAN_KIND.- No-agent behavior: neither agent attribute nor span kind is set.
This gives clear coverage of the new agent-handling branches without over-specifying unrelated metadata behavior.
You might optionally add an assertion that
ai.telemetry.metadata.agentis removed in the root-span test to mirror earlier metadata-removal expectations, but current coverage is already solid.packages/sample-app/src/sample_vercel_ai_agent.ts (1)
222-229: Conversation turn calculation is slightly off inside the system prompt/metadataYou use
this.conversationHistory.length / 2 + 1both for logging and in the system prompt/metadata. Before adding the current user message this yields an integer (correct turn), but after pushing the user message it becomes fractional (e.g.,1.5) for the same turn in the system prompt andexperimental_telemetry.metadata.conversationTurn.To keep turn numbers consistent and integer, consider normalizing the expression, e.g.:
- console.log( - `📋 Session: ${this.sessionId} | User: ${ - this.userId || "anonymous" - } | Turn: ${this.conversationHistory.length / 2 + 1}\n`, - ); + const turn = + Math.floor(this.conversationHistory.length / 2) + 1; + console.log( + `📋 Session: ${this.sessionId} | User: ${ + this.userId || "anonymous" + } | Turn: ${turn}\n`, + ); @@ -Conversation Turn: ${this.conversationHistory.length / 2 + 1}`, +Conversation Turn: ${turn}`, @@ - conversationTurn: this.conversationHistory.length / 2 + 1, + conversationTurn: turn,Also applies to: 255-257, 273-278
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)
367-410: Agent metadata handling looks correct; confirm interaction with span renaming orderThe new agent handling in
transformTelemetryMetadataand the plumbedspanNameargument intransformLLMSpans/transformAiSdkSpanAttributeslook logically sound:
ai.telemetry.metadata.agentis promoted to:
SpanAttributes.GEN_AI_AGENT_NAMEon all spans for context.SpanAttributes.TRACELOOP_SPAN_KIND = "agent"only whenspanName === AI_GENERATE_TEXT(root span).- Association properties continue to be set for all metadata keys and original
ai.telemetry.metadata.*keys are still removed, preserving previous behavior.One subtle point to verify:
TRACELOOP_SPAN_KINDis gated onspanName === AI_GENERATE_TEXT, but spans may be renamed bytransformAiSdkSpanNames(ai.generateText→run.ai). This logic assumes that attribute transformation runs while the span name is still the raw AI SDK name.If there’s any chance
transformAiSdkSpanNamesruns beforetransformAiSdkSpanAttributes, you may want to:
- Either ensure ordering (attributes first, then names), or
- Broaden the check to also recognize the renamed root span, e.g. by comparing against
HANDLED_SPAN_NAMES[AI_GENERATE_TEXT]as well.Please confirm the actual order in which
transformAiSdkSpanNamesandtransformAiSdkSpanAttributesare invoked in your OTEL pipeline so root spans reliably gettraceloop.span.kind = "agent".Also applies to: 421-435, 468-469
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
packages/sample-app/package.json(1 hunks)packages/sample-app/src/sample_vercel_ai_agent.ts(1 hunks)packages/sample-app/src/sample_vercel_ai_agent_simple.ts(1 hunks)packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts(6 hunks)packages/traceloop-sdk/test/ai-sdk-transformations.test.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Import AI/LLM semantic attribute constants from @traceloop/ai-semantic-conventions rather than hardcoding strings
Files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
packages/traceloop-sdk/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/traceloop-sdk/**/*.{ts,tsx}: Use the provided decorators (@workflow, @task, @agent) for workflow/task/agent spans instead of re-implementing them
For manual LLM operations, use trace.withLLMSpan from @traceloop/node-server-sdk
Files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
packages/*/package.json
📄 CodeRabbit inference engine (CLAUDE.md)
Use workspace:* for intra-repo package dependencies in package.json
Files:
packages/sample-app/package.json
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
Applied to files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
Applied to files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/sample-app/src/sample_vercel_ai_agent.tspackages/sample-app/src/sample_vercel_ai_agent_simple.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them
Applied to files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/sample-app/src/sample_vercel_ai_agent.tspackages/sample-app/src/sample_vercel_ai_agent_simple.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : For manual LLM operations, use trace.withLLMSpan from traceloop/node-server-sdk
Applied to files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/ai-semantic-conventions/src/SemanticAttributes.ts : Define all AI/LLM span attribute constants in packages/ai-semantic-conventions/src/SemanticAttributes.ts
Applied to files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
🧬 Code graph analysis (4)
packages/traceloop-sdk/test/ai-sdk-transformations.test.ts (2)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)
transformLLMSpans(421-435)packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
SpanAttributes(17-63)
packages/sample-app/src/sample_vercel_ai_agent.ts (2)
packages/traceloop-sdk/src/lib/tracing/decorators.ts (2)
tool(290-296)agent(282-288)packages/traceloop-sdk/src/lib/client/dataset/row.ts (1)
data(26-28)
packages/sample-app/src/sample_vercel_ai_agent_simple.ts (2)
packages/traceloop-sdk/src/lib/tracing/decorators.ts (2)
tool(290-296)task(274-280)packages/traceloop-sdk/src/lib/client/experiment/experiment.ts (1)
createTask(168-194)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)
packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
SpanAttributes(17-63)
🔇 Additional comments (1)
packages/sample-app/package.json (1)
23-24: New Vercel agent scripts are consistent with existing patternsThe two new scripts follow the established
npm run build && node dist/...convention and correctly point to the new agent entrypoints. No issues from a tooling or consistency standpoint.
| async function runSimpleAgent() { | ||
| // Generate session metadata for tracking | ||
| const sessionId = `simple_session_${Date.now()}_${crypto.randomUUID().substring(0, 8)}`; | ||
| const userId = "demo_user_simple"; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Import randomUUID instead of relying on global crypto
sessionId is built with crypto.randomUUID(), but crypto is not imported. As with the other agent sample, this may throw ReferenceError: crypto is not defined on Node runtimes where Web Crypto is not exposed as a global, despite "node": ">=14" in package.json.
Safer pattern:
-import * as traceloop from "@traceloop/node-server-sdk";
+import * as traceloop from "@traceloop/node-server-sdk";
+import { randomUUID } from "crypto";
@@
- const sessionId = `simple_session_${Date.now()}_${crypto.randomUUID().substring(
- 0,
- 8,
- )}`;
+ const sessionId = `simple_session_${Date.now()}_${randomUUID().substring(
+ 0,
+ 8,
+ )}`;Please verify this against the Node versions you expect contributors to use when running the sample app.
---
🏁 Script executed:
```shell
#!/bin/bash
# Check if crypto is imported in the sample file
echo "=== Checking imports in sample_vercel_ai_agent_simple.ts ==="
head -30 packages/sample-app/src/sample_vercel_ai_agent_simple.ts
echo -e "\n=== Checking for crypto references ==="
rg -n "crypto\|randomUUID" packages/sample-app/src/sample_vercel_ai_agent_simple.ts -A2 -B2
echo -e "\n=== Checking package.json Node version ==="
cat packages/sample-app/package.json | jq '.engines.node, .node'
Length of output: 1023
🌐 Web query:
When did Node.js crypto.randomUUID become available as global?
💡 Result:
crypto.randomUUID became available on the global crypto (globalThis.crypto.randomUUID) in Node.js v16.7.0 (implementation landed in the v16.7.0 release). [1][2]
Sources:
- Node.js Web Crypto docs (shows crypto.randomUUID added in v16.7.0). [1]
- Node.js v16.7.0 release notes (commit: "implement webcrypto.randomUUID"). [2]
🏁 Script executed:
#!/bin/bash
# Check what's actually at lines 102-106
echo "=== Lines 102-106 of sample_vercel_ai_agent_simple.ts ==="
sed -n '102,106p' packages/sample-app/src/sample_vercel_ai_agent_simple.ts
echo -e "\n=== Context: lines 95-115 ==="
sed -n '95,115p' packages/sample-app/src/sample_vercel_ai_agent_simple.tsLength of output: 915
Import randomUUID instead of relying on global crypto
crypto.randomUUID became available on the global crypto (globalThis.crypto.randomUUID) in Node.js v16.7.0, but the package.json specifies ">=14". Code at line 104 uses crypto.randomUUID() without importing it, which will throw ReferenceError: crypto is not defined on Node 14 and 15.
Safer pattern:
import * as traceloop from "@traceloop/node-server-sdk";
+import { randomUUID } from "crypto";
import { openai } from "@ai-sdk/openai";Then at line 104:
- const sessionId = `simple_session_${Date.now()}_${crypto.randomUUID().substring(0, 8)}`;
+ const sessionId = `simple_session_${Date.now()}_${randomUUID().substring(0, 8)}`;Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In packages/sample-app/src/sample_vercel_ai_agent_simple.ts around lines 102 to
106, the code calls crypto.randomUUID() but package.json allows Node >=14 where
globalThis.crypto may be undefined; import the function explicitly (e.g., import
{ randomUUID } from "crypto") at the top of the file and replace
crypto.randomUUID() with randomUUID() (or call randomUUID().substring(0,8) as
before) so the code works on Node 14/15.
| constructor(userId?: string) { | ||
| this.sessionId = `session_${Date.now()}_${crypto.randomUUID().substring(0, 8)}`; | ||
| this.userId = userId; | ||
| console.log(`🆔 Initialized agent with session: ${this.sessionId}`); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Avoid relying on global crypto.randomUUID for Node compatibility
crypto.randomUUID() is used without importing crypto. On many Node versions (especially earlier ones still covered by "node": ">=14" in package.json), crypto is not a global, which would cause a ReferenceError at runtime.
Consider importing from the Node crypto module instead:
-import * as traceloop from "@traceloop/node-server-sdk";
+import * as traceloop from "@traceloop/node-server-sdk";
+import { randomUUID } from "crypto";
@@
- constructor(userId?: string) {
- this.sessionId = `session_${Date.now()}_${crypto.randomUUID().substring(
- 0,
- 8,
- )}`;
+ constructor(userId?: string) {
+ this.sessionId = `session_${Date.now()}_${randomUUID().substring(0, 8)}`;This keeps the sample working across a wider range of Node runtimes.
Please double-check your targeted Node versions and ensure this import pattern matches your tsconfig/module setup.
🏁 Script executed:
#!/bin/bash
# Check the actual state of sample_vercel_ai_agent.ts file
find . -name "sample_vercel_ai_agent.ts" -type f 2>/dev/null | head -5Length of output: 51
🏁 Script executed:
#!/bin/bash
# Check imports and crypto usage in the file
cat packages/sample-app/src/sample_vercel_ai_agent.ts | head -50Length of output: 1195
🏁 Script executed:
#!/bin/bash
# Check package.json for Node version requirement
cat package.json | grep -A 2 '"engines"' Length of output: 0
🏁 Script executed:
#!/bin/bash
# Look for any crypto imports in the entire file
grep -n "crypto\|randomUUID" packages/sample-app/src/sample_vercel_ai_agent.tsLength of output: 88
🏁 Script executed:
#!/bin/bash
# Check the full constructor context
sed -n '210,230p' packages/sample-app/src/sample_vercel_ai_agent.tsLength of output: 754
🌐 Web query:
Node.js crypto.randomUUID() global availability which versions
💡 Result:
-
crypto.randomUUID() (on the crypto module): added in Node.js v14.17.0 (also in v15.6.0). [1][2]
-
globalThis.crypto (Web Crypto) — which exposes crypto.randomUUID as a global: added in v16.15.0 / v17.6.0 (experimental earlier), became unflagged in v19.0.0 and marked non‑experimental later. [3][4]
Sources:
[1] Node.js v14 docs — crypto.randomUUID (Added in: v14.17.0).
[2] Node.js v18/v20 docs — crypto.randomUUID (Added in: v15.6.0, v14.17.0).
[3] Node.js globals docs — crypto global added in v16.15.0 / v17.6.0.
[4] Node.js globals docs — global Web Crypto unflagged in v19.0.0.
🏁 Script executed:
#!/bin/bash
# Check sample-app package.json for Node version requirement
cat packages/sample-app/package.json | grep -A 5 '"engines"' Length of output: 127
🏁 Script executed:
#!/bin/bash
# Alternative: search for engine or node version anywhere in sample-app package.json
cat packages/sample-app/package.json | head -20Length of output: 1197
Import randomUUID from Node's crypto module
The code at line 217 uses crypto.randomUUID() without importing crypto. The global crypto object is only available starting Node v16.15.0/v17.6.0, but the package targets "node": ">=14", which includes versions where this global doesn't exist and would cause a ReferenceError.
Import randomUUID from the crypto module instead, which is available in Node v14.17.0+:
import * as traceloop from "@traceloop/node-server-sdk";
+import { randomUUID } from "crypto";
import { openai } from "@ai-sdk/openai";- this.sessionId = `session_${Date.now()}_${crypto.randomUUID().substring(0, 8)}`;
+ this.sessionId = `session_${Date.now()}_${randomUUID().substring(0, 8)}`;This ensures the sample works across the declared Node version range.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In packages/sample-app/src/sample_vercel_ai_agent.ts around lines 216 to 220,
the constructor calls crypto.randomUUID() without importing crypto which can
break on Node <16 where global crypto may be undefined; import the randomUUID
function from Node's 'crypto' module at the top of the file (e.g. import {
randomUUID } from 'crypto') and replace crypto.randomUUID() with randomUUID() so
the code works across the declared Node >=14 range.
The span name transformation happens before attribute transformation in the processing pipeline. This fix ensures we check for the transformed span name "run.ai" instead of the original "ai.generateText" when determining if we should set traceloop.span.kind to "agent". 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
b396451 to
258c731
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)
401-411: Consider defining span kind values as constants.The implementation correctly uses
SpanAttributes.TRACELOOP_SPAN_KINDfor the attribute key, but the value"agent"on line 409 is hardcoded. For consistency with the codebase pattern of importing constants from@traceloop/ai-semantic-conventions, consider defining span kind values (e.g.,SPAN_KIND_AGENT,SPAN_KIND_WORKFLOW,SPAN_KIND_TASK) as constants inpackages/ai-semantic-conventions/src/SemanticAttributes.ts.Based on learnings, attribute constants should be imported from @traceloop/ai-semantic-conventions rather than hardcoded.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts(6 hunks)packages/traceloop-sdk/test/ai-sdk-transformations.test.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Import AI/LLM semantic attribute constants from @traceloop/ai-semantic-conventions rather than hardcoding strings
Files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
packages/traceloop-sdk/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/traceloop-sdk/**/*.{ts,tsx}: Use the provided decorators (@workflow, @task, @agent) for workflow/task/agent spans instead of re-implementing them
For manual LLM operations, use trace.withLLMSpan from @traceloop/node-server-sdk
Files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : For manual LLM operations, use trace.withLLMSpan from traceloop/node-server-sdk
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
Applied to files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
Applied to files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : For manual LLM operations, use trace.withLLMSpan from traceloop/node-server-sdk
Applied to files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them
Applied to files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/ai-semantic-conventions/src/SemanticAttributes.ts : Define all AI/LLM span attribute constants in packages/ai-semantic-conventions/src/SemanticAttributes.ts
Applied to files:
packages/traceloop-sdk/test/ai-sdk-transformations.test.tspackages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
🧬 Code graph analysis (2)
packages/traceloop-sdk/test/ai-sdk-transformations.test.ts (2)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)
transformLLMSpans(422-436)packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
SpanAttributes(17-63)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)
packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
SpanAttributes(17-63)
🔇 Additional comments (5)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (2)
422-436: LGTM!The parameter threading is clean and correctly propagates the span name for agent detection logic.
469-469: LGTM!Correctly passes the span name to enable agent detection based on span hierarchy.
packages/traceloop-sdk/test/ai-sdk-transformations.test.ts (3)
1749-1782: LGTM!Comprehensive test coverage for agent detection on root spans. The test correctly validates that both
gen_ai.agent.nameandtraceloop.span.kindare set, while ensuring association properties are preserved.
1784-1806: LGTM!Excellent test case validating the distinction between root and child span behavior. Correctly verifies that agent name propagates while span kind remains unset on child spans.
1808-1826: LGTM!Important negative test case ensuring no false positives. Correctly validates that agent-related attributes are not set when agent metadata is absent.
Use the TraceloopSpanKindValues.AGENT enum constant instead of the string literal "agent" for consistency with the rest of the codebase. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (2)
370-377: Agent detection and root-span handling look correct; consider decoupling from raw span nameThe new
spanName?parameter andagentNamehandling correctly:
- Detect
ai.telemetry.metadata.agent.- Set
SpanAttributes.GEN_AI_AGENT_NAMEon all spans with that metadata.- Set
TRACELOOP_SPAN_KIND = TraceloopSpanKindValues.AGENTonly whenspanName === HANDLED_SPAN_NAMES[AI_GENERATE_TEXT]("run.ai"), matching the intent to mark only the root AI span as an agent span.One minor maintainability concern: root-span detection is now implicitly tied to the transformed span name string. If naming conventions change in the future, this logic must be kept in sync with
HANDLED_SPAN_NAMESand the place where names are transformed.A small refactor to consider (optional):
- Introduce a helper like
isRootAiRunSpan(spanName: string | undefined): boolean(co-located withHANDLED_SPAN_NAMES) and call it here, so renames only need to be updated in one place.This keeps behavior identical while making the coupling more explicit.
Also applies to: 391-415
426-440: Span name plumb-through for agent detection is sound; watch call-order assumptionsPassing
spanName?throughtransformLLMSpansintotransformTelemetryMetadata, and then callingtransformLLMSpans(span.attributes, span.name)fromtransformAiSdkSpanAttributes, is a clean way to give metadata transformations access to the final span name.The only implicit assumption is that
transformAiSdkSpanNames(which rewrites names to"run.ai","text.generate", etc.) runs beforetransformAiSdkSpanAttributes, so thespan.nameseen here is already transformed. Tests likely cover this, but it’s worth keeping in mind for any future reordering of processors.If these two always need to be used together in a specific order, an optional follow-up would be to:
- Add a brief comment at the call site where both transformers are wired, or
- Wrap them in a small helper that enforces order, rather than relying on convention.
Functionally, the current change looks correct and backward-compatible since
spanNameis optional.Also applies to: 473-473
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts(7 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Import AI/LLM semantic attribute constants from @traceloop/ai-semantic-conventions rather than hardcoding strings
Files:
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
packages/traceloop-sdk/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/traceloop-sdk/**/*.{ts,tsx}: Use the provided decorators (@workflow, @task, @agent) for workflow/task/agent spans instead of re-implementing them
For manual LLM operations, use trace.withLLMSpan from @traceloop/node-server-sdk
Files:
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : For manual LLM operations, use trace.withLLMSpan from traceloop/node-server-sdk
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
Applied to files:
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
Applied to files:
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/ai-semantic-conventions/src/SemanticAttributes.ts : Define all AI/LLM span attribute constants in packages/ai-semantic-conventions/src/SemanticAttributes.ts
Applied to files:
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them
Applied to files:
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : For manual LLM operations, use trace.withLLMSpan from traceloop/node-server-sdk
Applied to files:
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📚 Learning: 2025-08-12T13:57:05.901Z
Learnt from: galzilber
Repo: traceloop/openllmetry-js PR: 643
File: packages/traceloop-sdk/test/datasets-final.test.ts:97-105
Timestamp: 2025-08-12T13:57:05.901Z
Learning: The traceloop-sdk uses a response transformer (`transformApiResponse` in `packages/traceloop-sdk/src/lib/utils/response-transformer.ts`) that converts snake_case API responses to camelCase for SDK interfaces. Raw API responses use snake_case but SDK consumers see camelCase fields.
Applied to files:
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
🧬 Code graph analysis (1)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)
packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
SpanAttributes(17-63)
🔇 Additional comments (1)
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (1)
2-5: Good: using semantic-convention enum for span kind instead of string literalsImporting
TraceloopSpanKindValuesfrom@traceloop/ai-semantic-conventionskeeps span-kind values centralized and avoids hardcoded strings, consistent with the semantic-conventions guideline. No issues here.
When tool calls are executed in AI SDK, set the traceloop.span.kind attribute to "tool" to properly classify these spans in the tracing hierarchy. This ensures consistent span categorization across the SDK. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Set traceloop.entity.name attribute for better span identification: - Agent spans: entity name set to agent name from metadata - Tool call spans: entity name set to tool name from ai.toolCall.name This provides consistent entity naming across all span types and improves trace visualization and analysis. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Important
Looks good to me! 👍
Reviewed 1e25666 in 54 seconds. Click for details.
- Reviewed
70lines of code in2files - Skipped
0files when reviewing. - Skipped posting
3draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:411
- Draft comment:
Agent detection now sets TRACELOOP_ENTITY_NAME using the detected agent name on root spans. Ensure that agentName is non-empty/truthy as expected. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%The comment is asking the author to ensure thatagentNameis non-empty/truthy, which violates the rule against asking the author to ensure behavior. It doesn't provide a specific suggestion or point out a specific issue with the code.
2. packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:457
- Draft comment:
Tool call transformation now sets TRACELOOP_ENTITY_NAME from 'ai.toolCall.name', ensuring consistency for tool spans. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%This comment is purely informative, describing what the code change does without suggesting any improvements or asking for clarifications. It doesn't provide any actionable feedback or raise any concerns about the code.
3. packages/traceloop-sdk/test/ai-sdk-transformations.test.ts:1750
- Draft comment:
The new tests for agent detection are comprehensive. Consider adding an edge case for an empty agent string to further validate behavior. - Reason this comment was not posted:
Comment was not on a location in the diff, so it can't be submitted as a review comment.
Workflow ID: wflow_LHWXjybnniT9vKfc
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
AI SDK only sets telemetry metadata on the root generateText span, not on child tool call spans. This adds trace-level agent name storage and propagation to ensure all spans in an agent trace (including tool calls) have the gen_ai.agent.name attribute. Implementation: - Store agent names in a Map keyed by trace ID - When a span has agent name, store it for the trace - When a span doesn't have agent name but its trace does, propagate it - Clean up old traces (keep last 1000) to prevent memory leaks 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caution
Changes requested ❌
Reviewed a2d51e6 in 1 minute and 49 seconds. Click for details.
- Reviewed
42lines of code in1files - Skipped
0files when reviewing. - Skipped posting
1draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. packages/traceloop-sdk/src/lib/tracing/span-processor.ts:27
- Draft comment:
Global Map 'traceAgentNames' is used for agent name propagation across spans. This approach may cause memory retention issues in long-running processes. Consider using an LRU cache or WeakMap for better cleanup and potential concurrency safety. - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 35% vs. threshold = 50% The comment is definitely about a change in the diff - the Map was added in this PR. The code does implement a basic cleanup mechanism (keeping only 1000 traces), which shows the author was aware of memory concerns. The comment suggests alternatives (LRU cache or WeakMap) but doesn't provide strong evidence that the current approach is problematic. WeakMap wouldn't work here since trace IDs are strings (primitives), not objects. An LRU cache might be better than the current FIFO approach, but the current implementation seems reasonable for the use case. The comment is somewhat speculative ("may cause memory retention issues") rather than pointing to a definite problem. The author already implemented cleanup logic, so they considered this concern. The comment does raise a valid architectural concern about using a global Map in a long-running process. The suggestion for an LRU cache is reasonable and actionable. The current FIFO cleanup (deleting the first key) is less optimal than LRU for this use case. This could be considered a code quality improvement suggestion, which the rules say are good if actionable and clear. While the comment is actionable, it's somewhat speculative ("may cause") and the author already implemented cleanup logic showing awareness of memory concerns. The WeakMap suggestion is incorrect (can't use strings as keys), which undermines the comment's credibility. The LRU cache suggestion is valid but not critical - the current approach with a 1000-entry limit is reasonable for most use cases. This feels more like a "nice to have" optimization rather than a clear issue. The comment makes a reasonable suggestion about using an LRU cache, but it's speculative and the author already implemented cleanup logic. The WeakMap suggestion is technically incorrect. Given the rule to only keep comments with STRONG EVIDENCE of correctness, and that this is more of an optimization suggestion than a clear problem, I should lean toward deleting it.
Workflow ID: wflow_9uaaDMOYqTZwlJTb
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
This reverts commit a2d51e6.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Important
Looks good to me! 👍
Reviewed fc09b89 in 1 minute and 16 seconds. Click for details.
- Reviewed
42lines of code in1files - Skipped
0files when reviewing. - Skipped posting
2draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. packages/traceloop-sdk/src/lib/tracing/span-processor.ts:24
- Draft comment:
Removed 'traceAgentNames' Map which was used for propagating the agent name. Ensure that the new agent detection via transformAiSdkSpanAttributes fully handles agent metadata propagation across child spans. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%The comment is suggesting to ensure that a new method fully handles a specific functionality after a removal of a map. It is asking for confirmation of the new method's capability, which is not allowed by the rules.
2. packages/traceloop-sdk/src/lib/tracing/span-processor.ts:237
- Draft comment:
Removed manual agent propagation logic in onSpanEnd. Confirm that transformAiSdkSpanAttributes now correctly assigns the agent attribute to spans, including child spans without an explicit agent name. - Reason this comment was not posted:
Comment was on unchanged code.
Workflow ID: wflow_wzN0uium1bgJKOQ4
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
…ame trace"" This reverts commit fc09b89.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caution
Changes requested ❌
Reviewed 2449e59 in 2 minutes and 10 seconds. Click for details.
- Reviewed
42lines of code in1files - Skipped
0files when reviewing. - Skipped posting
2draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. packages/traceloop-sdk/src/lib/tracing/span-processor.ts:249
- Draft comment:
Review the cleanup logic: capping at 1000 entries via removing the first key may be suboptimal; consider a more predictable eviction mechanism. - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 20% vs. threshold = 50% The comment is about changed code (the agent name propagation logic is new). However, the comment is somewhat vague - it says the approach "may be suboptimal" and suggests "a more predictable eviction mechanism" without being specific about what's wrong or what should be done instead. The current approach (removing the first key) is actually a reasonable FIFO approach for a Map in JavaScript, since Maps maintain insertion order. The comment doesn't explain why this is problematic or what specific alternative should be used (LRU cache? Different threshold? Different data structure?). This feels like a code quality suggestion that's not actionable enough - it's speculative ("may be suboptimal") rather than definitive, and doesn't provide clear guidance on what to change. The cleanup logic could genuinely be improved - for instance, an LRU cache would be better if traces are accessed multiple times, or batch deletion might be more efficient than deleting one entry at a time. The comment might be pointing to a legitimate concern about memory management in a production system. While there might be better approaches, the comment doesn't provide specific, actionable guidance. It uses hedging language ("may be suboptimal") and vague suggestions ("more predictable eviction mechanism"). The current approach is actually predictable (FIFO based on Map insertion order) and functional. Without concrete evidence of a problem or a specific alternative, this is more of a speculative code quality comment that isn't actionable enough to be useful. The comment is too vague and speculative to be actionable. It doesn't explain what's wrong with the current approach or provide specific alternatives. The current FIFO approach using Map's insertion order is actually predictable and reasonable for this use case.
2. packages/traceloop-sdk/src/lib/tracing/span-processor.ts:257
- Draft comment:
The non-null assertion (traceAgentNames.get(traceId)!) is safe due to the preceding check, but consider refactoring for clarity. - Reason this comment was not posted:
Comment looked like it was already resolved.
Workflow ID: wflow_ImStAsbz2JZzSbZb
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
| type AllInstrumentationLibraries = typeof ALL_INSTRUMENTATION_LIBRARIES; | ||
|
|
||
| // Store agent names per trace for propagation to child spans (tool calls) | ||
| const traceAgentNames = new Map<string, string>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider a more robust eviction strategy (e.g. LRU/timed eviction) for traceAgentNames to prevent memory buildup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
packages/traceloop-sdk/src/lib/tracing/span-processor.ts (2)
249-254: Inadequate cleanup removes only one entry.The cleanup logic removes only one entry when
traceAgentNames.sizeexceeds 1000. If multiple spans are processed in quick succession, the Map size can grow beyond the threshold.Apply this diff to remove excess entries until the size is within bounds:
// Clean up old traces (keep only last 1000 traces) - if (traceAgentNames.size > 1000) { + while (traceAgentNames.size > 1000) { const firstKey = traceAgentNames.keys().next().value; if (firstKey) { traceAgentNames.delete(firstKey); } }
27-28: Consider trace completion cleanup and bounded growth.The module-scoped Map lacks a mechanism to detect when traces complete, so entries accumulate until the 1000-entry threshold is reached. Additionally, the cleanup at lines 249-254 removes only one entry per insertion when the limit is exceeded, meaning the Map can still grow beyond 1000 if multiple spans are processed rapidly.
Consider:
- Implementing a while-loop in the cleanup logic to ensure size stays within bounds
- Adding a TTL mechanism or event-based cleanup when traces complete to prevent stale entries from consuming memory
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
packages/traceloop-sdk/src/lib/tracing/span-processor.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Import AI/LLM semantic attribute constants from @traceloop/ai-semantic-conventions rather than hardcoding strings
Files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
packages/traceloop-sdk/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/traceloop-sdk/**/*.{ts,tsx}: Use the provided decorators (@workflow, @task, @agent) for workflow/task/agent spans instead of re-implementing them
For manual LLM operations, use trace.withLLMSpan from @traceloop/node-server-sdk
Files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : For manual LLM operations, use trace.withLLMSpan from traceloop/node-server-sdk
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/ai-semantic-conventions/src/SemanticAttributes.ts : Define all AI/LLM span attribute constants in packages/ai-semantic-conventions/src/SemanticAttributes.ts
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/src/lib/node-server-sdk.ts : Register new instrumentation packages during SDK initialization
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
🧬 Code graph analysis (1)
packages/traceloop-sdk/src/lib/tracing/span-processor.ts (1)
packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
SpanAttributes(17-63)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build and test
| span.attributes[SpanAttributes.GEN_AI_AGENT_NAME] = | ||
| traceAgentNames.get(traceId)!; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify that direct mutation of ReadableSpan.attributes is safe.
The code directly mutates span.attributes after the span has ended. The ReadableSpan interface suggests immutability, and this pattern may cause issues with certain span implementations or exporters that expect attributes to remain unchanged post-collection.
Run the following script to check if other parts of the codebase mutate ReadableSpan attributes similarly:
🏁 Script executed:
#!/bin/bash
# Description: Search for other instances of ReadableSpan attribute mutations to verify this pattern
# Search for direct assignments to span.attributes after onEnd
rg -n -A3 -B3 'span\.attributes\[.*\]\s*=' --type=tsLength of output: 6217
🏁 Script executed:
#!/bin/bash
# Get context around the span-processor.ts mutation (lines 240-270)
echo "=== span-processor.ts context ==="
sed -n '240,270p' packages/traceloop-sdk/src/lib/tracing/span-processor.ts
echo ""
echo "=== ai-sdk-transformations.ts context ==="
sed -n '430,465p' packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
echo ""
echo "=== Method signature for span-processor.ts onEnd ==="
grep -n "onEnd" packages/traceloop-sdk/src/lib/tracing/span-processor.ts | head -5Length of output: 2549
🏁 Script executed:
#!/bin/bash
# Find where transformToolCalls is called
echo "=== transformToolCalls usage ==="
rg -n "transformToolCalls" packages/traceloop-sdk/src/lib/tracing/
echo ""
echo "=== Full onSpanEnd method definition ==="
sed -n '107,275p' packages/traceloop-sdk/src/lib/tracing/span-processor.ts
echo ""
echo "=== Check for ReadableSpan type definition in codebase ==="
rg -n "ReadableSpan" packages/traceloop-sdk/src/lib/tracing/span-processor.ts | head -3Length of output: 5183
🏁 Script executed:
#!/bin/bash
# Find transformAiSdkSpanAttributes implementation
echo "=== transformAiSdkSpanAttributes implementation ==="
rg -n "const transformAiSdkSpanAttributes" packages/traceloop-sdk/src/lib/tracing/ -A 5
echo ""
echo "=== Tests for agent name propagation ==="
rg -n "traceAgentNames\|GEN_AI_AGENT_NAME" packages/traceloop-sdk/test/ -B 2 -A 2
echo ""
echo "=== Check imports in span-processor.ts ==="
head -20 packages/traceloop-sdk/src/lib/tracing/span-processor.tsLength of output: 1327
🌐 Web query:
OpenTelemetry ReadableSpan attributes mutability - is it safe to mutate span.attributes in onEnd callback
💡 Result:
Short answer: No — do not mutate span.attributes in onEnd. The OpenTelemetry spec requires that the span passed to OnEnd is a readable (ended) span and must not be modified; if you need to change attributes at end-time do it in the OnEnding/OnEnding (or the span processor callback invoked while the span is still mutable) or earlier (onStart / via a ReadWriteSpan). [1][2]
Sources:
- OpenTelemetry tracing SDK spec — OnEnding (span still mutable) and OnEnd (ended/read-only). [1]
- Language SDK docs showing ReadWriteSpan/onEnd usage guidance. [2]
Fix mutations of ReadableSpan.attributes — direct modification in onEnd violates OpenTelemetry specification.
The code mutates span.attributes in the onEnd callback, which violates the OpenTelemetry specification. The span passed to onEnd is an ended/read-only span and must not be modified; attribute changes must happen during onEnding (while span is still mutable) or onStart.
Move mutations to an earlier lifecycle stage:
- packages/traceloop-sdk/src/lib/tracing/span-processor.ts:257–258 — Agent name propagation should use onStart or store data before span ends
- packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts:448–460 — transformToolCalls and related mutations should be applied before span collection completes, not in onEnd
Added comprehensive integration test using Polly.js recording to verify: - Root span gets agent name, span kind, and entity name from metadata - Tool call spans inherit agent name from parent and get tool span kind - Child LLM spans inherit agent name but don't get span kind Using trace-level agent name storage for now (will be improved later). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive integration test using Polly.js to verify: - Root span (run.ai) receives agent attributes from metadata - Agent name propagates to tool call spans - Tool spans receive proper span kind and entity name - Child LLM spans inherit agent name but not span kind Also adds zod as dev dependency for AI SDK tool schema definitions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Important
Looks good to me! 👍
Reviewed e49e8ad in 1 minute and 56 seconds. Click for details.
- Reviewed
238lines of code in3files - Skipped
1files when reviewing. - Skipped posting
5draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. packages/traceloop-sdk/package.json:117
- Draft comment:
Verify if 'zod' is needed as a runtime dependency. If it's only used in tests or non‐runtime code, consider moving it to devDependencies. - Reason this comment was not posted:
Comment looked like it was already resolved.
2. packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts:39
- Draft comment:
Added a 30s timeout for the test suite. Ensure this duration is appropriate for external calls and avoids flakiness. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%The comment is asking the PR author to ensure that the 30s timeout is appropriate, which violates the rule against asking the author to confirm or ensure things. It doesn't provide a specific suggestion or point out a clear issue with the code.
3. packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts:86
- Draft comment:
Updated the tool definition to use 'inputSchema' (with descriptive fields) instead of 'parameters'. This improves clarity and aligns with the new API. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%This comment is purely informative, explaining a change that was made without suggesting any action or asking for clarification. It doesn't provide any actionable feedback or raise any concerns about the code.
4. packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts:105
- Draft comment:
The execute function now returns full input details (operation, a, b) along with result. Confirm downstream consumers can handle this updated structure. - Reason this comment was not posted:
Comment was not on a location in the diff, so it can't be submitted as a review comment.
5. packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts:149
- Draft comment:
The assertion for 'result.text' has been removed. Ensure that this change is intentional and that consumers no longer expect a 'text' property in the response. - Reason this comment was not posted:
Comment was not on a location in the diff, so it can't be submitted as a review comment.
Workflow ID: wflow_jREr53N8fCMeQtny
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (3)
packages/traceloop-sdk/package.json(1 hunks)packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-propagate-agent-name-to-tool-call-spans_3577231859/recording.har(1 hunks)packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-propagate-agent-name-to-tool-call-spans_3577231859/recording.har
🧰 Additional context used
📓 Path-based instructions (4)
packages/*/package.json
📄 CodeRabbit inference engine (CLAUDE.md)
Use workspace:* for intra-repo package dependencies in package.json
Files:
packages/traceloop-sdk/package.json
packages/traceloop-sdk/package.json
📄 CodeRabbit inference engine (CLAUDE.md)
When adding a new instrumentation package, add it to the main SDK dependencies
Files:
packages/traceloop-sdk/package.json
packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Import AI/LLM semantic attribute constants from @traceloop/ai-semantic-conventions rather than hardcoding strings
Files:
packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
packages/traceloop-sdk/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/traceloop-sdk/**/*.{ts,tsx}: Use the provided decorators (@workflow, @task, @agent) for workflow/task/agent spans instead of re-implementing them
For manual LLM operations, use trace.withLLMSpan from @traceloop/node-server-sdk
Files:
packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/package.json : When adding a new instrumentation package, add it to the main SDK dependencies
Applied to files:
packages/traceloop-sdk/package.json
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
Applied to files:
packages/traceloop-sdk/package.jsonpackages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : For manual LLM operations, use trace.withLLMSpan from traceloop/node-server-sdk
Applied to files:
packages/traceloop-sdk/package.jsonpackages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them
Applied to files:
packages/traceloop-sdk/package.jsonpackages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/src/lib/node-server-sdk.ts : Register new instrumentation packages during SDK initialization
Applied to files:
packages/traceloop-sdk/package.jsonpackages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
📚 Learning: 2025-08-13T08:00:42.668Z
Learnt from: galzilber
Repo: traceloop/openllmetry-js PR: 643
File: packages/traceloop-sdk/src/lib/interfaces/dataset.interface.ts:27-27
Timestamp: 2025-08-13T08:00:42.668Z
Learning: In packages/traceloop-sdk/src/lib/interfaces/dataset.interface.ts, when the user said "there is no date" in response to a comment about removing "date" from column type unions, they may have been referring to local changes not yet reflected in the PR branch, as the code still contained "date" in the union types at lines 27 and 43.
Applied to files:
packages/traceloop-sdk/package.json
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Use ts-mocha as the TypeScript test runner for package tests
Applied to files:
packages/traceloop-sdk/package.json
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
Applied to files:
packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts
🧬 Code graph analysis (1)
packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts (3)
packages/traceloop-sdk/test/test-setup.ts (2)
getSharedExporter(37-39)initializeSharedTraceloop(23-35)packages/traceloop-sdk/src/lib/tracing/decorators.ts (1)
tool(290-296)packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
SpanAttributes(17-63)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build and test
🔇 Additional comments (5)
packages/traceloop-sdk/package.json (1)
120-121: Addition of zod devDependency looks good.The addition of zod as a devDependency aligns with the PR objectives of adding agent detection unit tests and sample applications that rely on zod-based parameter schemas. The version constraint
^3.25.76is appropriate for a dev dependency, and the placement follows standard patterns (dev-only utilities in devDependencies, internal packages usingworkspace:*).packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts (4)
17-30: LGTM: Imports follow coding guidelines.The semantic constants are correctly imported from
@traceloop/ai-semantic-conventionsas per the coding guidelines. The AI SDK'stool()factory import is appropriate for this integration test scenario.
32-82: LGTM: Test setup and hooks are well-structured.The Polly configuration properly handles recording/replay modes, filters sensitive headers, and uses shared Traceloop initialization to avoid conflicts with other test suites. The cleanup in
afterEachensures proper test isolation.
84-114: LGTM: Comprehensive tool definition with proper validation.The calculator tool is well-implemented with zod schema validation, all operations covered, and proper error handling for division by zero. Using the AI SDK's
tool()factory is appropriate for this integration test.
116-153: LGTM: Proper use of workflow decorator.The test correctly uses
traceloop.withWorkflow()as per coding guidelines and properly configures telemetry metadata for agent detection testing. The span retrieval logic is straightforward.
| // Verify tool call span inherits agent name | ||
| if (toolSpan) { | ||
| assert.strictEqual( | ||
| toolSpan.attributes[SpanAttributes.GEN_AI_AGENT_NAME], | ||
| "test_calculator_agent", | ||
| "Tool span should inherit agent name from parent", | ||
| ); | ||
| assert.strictEqual( | ||
| toolSpan.attributes[SpanAttributes.TRACELOOP_SPAN_KIND], | ||
| "tool", | ||
| "Tool span should have span kind = tool", | ||
| ); | ||
| assert.ok( | ||
| toolSpan.attributes[SpanAttributes.TRACELOOP_ENTITY_NAME], | ||
| "Tool span should have entity name", | ||
| ); | ||
| } | ||
|
|
||
| // Verify child LLM span inherits agent name | ||
| if (childLLMSpan) { | ||
| assert.strictEqual( | ||
| childLLMSpan.attributes[SpanAttributes.GEN_AI_AGENT_NAME], | ||
| "test_calculator_agent", | ||
| "Child LLM span should inherit agent name from parent", | ||
| ); | ||
| // Child LLM span should NOT have span kind or entity name | ||
| assert.strictEqual( | ||
| childLLMSpan.attributes[SpanAttributes.TRACELOOP_SPAN_KIND], | ||
| undefined, | ||
| "Child LLM span should not have span kind", | ||
| ); | ||
| assert.strictEqual( | ||
| childLLMSpan.attributes[SpanAttributes.TRACELOOP_ENTITY_NAME], | ||
| undefined, | ||
| "Child LLM span should not have entity name", | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add assertions for tool and child LLM span existence.
The conditional checks for toolSpan and childLLMSpan (lines 196 and 214) mean these verifications are skipped if the spans don't exist. Given that the PR objectives explicitly mention verifying agent name propagation to tool call spans, these spans are expected to exist. The test should assert their existence to catch regressions.
Apply this diff to add the missing assertions:
);
// Verify tool call span inherits agent name
+ assert.ok(toolSpan, "Tool span should exist");
if (toolSpan) {
assert.strictEqual( }
// Verify child LLM span inherits agent name
+ assert.ok(childLLMSpan, "Child LLM span should exist");
if (childLLMSpan) {
assert.strictEqual(📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Verify tool call span inherits agent name | |
| if (toolSpan) { | |
| assert.strictEqual( | |
| toolSpan.attributes[SpanAttributes.GEN_AI_AGENT_NAME], | |
| "test_calculator_agent", | |
| "Tool span should inherit agent name from parent", | |
| ); | |
| assert.strictEqual( | |
| toolSpan.attributes[SpanAttributes.TRACELOOP_SPAN_KIND], | |
| "tool", | |
| "Tool span should have span kind = tool", | |
| ); | |
| assert.ok( | |
| toolSpan.attributes[SpanAttributes.TRACELOOP_ENTITY_NAME], | |
| "Tool span should have entity name", | |
| ); | |
| } | |
| // Verify child LLM span inherits agent name | |
| if (childLLMSpan) { | |
| assert.strictEqual( | |
| childLLMSpan.attributes[SpanAttributes.GEN_AI_AGENT_NAME], | |
| "test_calculator_agent", | |
| "Child LLM span should inherit agent name from parent", | |
| ); | |
| // Child LLM span should NOT have span kind or entity name | |
| assert.strictEqual( | |
| childLLMSpan.attributes[SpanAttributes.TRACELOOP_SPAN_KIND], | |
| undefined, | |
| "Child LLM span should not have span kind", | |
| ); | |
| assert.strictEqual( | |
| childLLMSpan.attributes[SpanAttributes.TRACELOOP_ENTITY_NAME], | |
| undefined, | |
| "Child LLM span should not have entity name", | |
| ); | |
| } | |
| // Verify tool call span inherits agent name | |
| assert.ok(toolSpan, "Tool span should exist"); | |
| if (toolSpan) { | |
| assert.strictEqual( | |
| toolSpan.attributes[SpanAttributes.GEN_AI_AGENT_NAME], | |
| "test_calculator_agent", | |
| "Tool span should inherit agent name from parent", | |
| ); | |
| assert.strictEqual( | |
| toolSpan.attributes[SpanAttributes.TRACELOOP_SPAN_KIND], | |
| "tool", | |
| "Tool span should have span kind = tool", | |
| ); | |
| assert.ok( | |
| toolSpan.attributes[SpanAttributes.TRACELOOP_ENTITY_NAME], | |
| "Tool span should have entity name", | |
| ); | |
| } | |
| // Verify child LLM span inherits agent name | |
| assert.ok(childLLMSpan, "Child LLM span should exist"); | |
| if (childLLMSpan) { | |
| assert.strictEqual( | |
| childLLMSpan.attributes[SpanAttributes.GEN_AI_AGENT_NAME], | |
| "test_calculator_agent", | |
| "Child LLM span should inherit agent name from parent", | |
| ); | |
| // Child LLM span should NOT have span kind or entity name | |
| assert.strictEqual( | |
| childLLMSpan.attributes[SpanAttributes.TRACELOOP_SPAN_KIND], | |
| undefined, | |
| "Child LLM span should not have span kind", | |
| ); | |
| assert.strictEqual( | |
| childLLMSpan.attributes[SpanAttributes.TRACELOOP_ENTITY_NAME], | |
| undefined, | |
| "Child LLM span should not have entity name", | |
| ); | |
| } |
🤖 Prompt for AI Agents
In packages/traceloop-sdk/test/ai-sdk-agent-integration.test.ts around lines 195
to 231, the test currently guards attribute checks with if (toolSpan) and if
(childLLMSpan) which silently skips checks when spans are missing; add explicit
existence assertions (e.g., assert.ok(toolSpan, "Expected toolSpan to exist")
and assert.ok(childLLMSpan, "Expected childLLMSpan to exist")) immediately
before inspecting their attributes so the test fails fast when spans are absent,
then keep the subsequent attribute assertions unchanged.
Implement hybrid cleanup for trace agent name map: - Primary: Clean up when root span ends (detected via parentSpanContext) - Safety net: TTL-based cleanup (5min) for orphaned entries - Probabilistic cleanup runs every ~100 spans This prevents memory leaks while ensuring precise cleanup timing. Also fixes root span detection by using parentSpanContext instead of parentSpanId, which is not always populated in exported spans. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Important
Looks good to me! 👍
Reviewed 3440e2c in 1 minute and 24 seconds. Click for details.
- Reviewed
177lines of code in2files - Skipped
0files when reviewing. - Skipped posting
4draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-propagate-agent-name-to-tool-call-spans_3577231859/recording.har:36
- Draft comment:
HAR recording updated with new response IDs, header, and timing values reflecting agent instrumentation. Ensure these test updates match the expected output. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
2. packages/traceloop-sdk/src/lib/tracing/span-processor.ts:27
- Draft comment:
TTL-based traceAgentNames map is a good approach for agent propagation. Consider adding unit tests for cleanupExpiredTraceAgentNames to cover edge cases. - Reason this comment was not posted:
Confidence changes required:33%<= threshold50%None
3. packages/traceloop-sdk/src/lib/tracing/span-processor.ts:52
- Draft comment:
The isRootSpan utility correctly identifies root spans; verify that this logic covers all edge cases per OTel specifications. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
4. packages/traceloop-sdk/src/lib/tracing/span-processor.ts:275
- Draft comment:
Agent propagation in onSpanEnd is clear. Storing the agent name and cleaning it up (especially for root spans and via probabilistic cleanup) is a neat low-overhead design. Consider tuning the 1% cleanup probability if trace volume increases. - Reason this comment was not posted:
Confidence changes required:33%<= threshold50%None
Workflow ID: wflow_EOi52ZnUZAjGcpqH
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
packages/traceloop-sdk/src/lib/tracing/span-processor.ts (1)
271-295: CRITICAL: ReadableSpan mutation violates OpenTelemetry specification.Lines 283-284 directly mutate
span.attributesafter the span has ended. As noted in previous reviews, the OpenTelemetry specification requires that spans passed toonEndare read-only and must not be modified. Attribute modifications must occur inonStartor while the span is still mutable (ReadWriteSpan).Required fix: Move agent name propagation to
onStartor use a different approach:Option 1: Store propagation data during onStart
Instead of modifying spans inonEnd, check the trace map duringonStartand set the attribute then:const onSpanStart = (span: Span): void => { + // Propagate agent name from trace if available + const traceId = span.spanContext().traceId; + const existingAgentName = traceAgentNames.get(traceId)?.agentName; + if (existingAgentName) { + span.setAttribute(SpanAttributes.GEN_AI_AGENT_NAME, existingAgentName); + } + const workflowName = context.active().getValue(WORKFLOW_NAME_KEY); // ... rest of onStart logicOption 2: Use SpanProcessor with ReadWriteSpan
Implement a custom span processor that has access toReadWriteSpanduring processing, allowing mutations before the span is marked as ended.Note: This issue blocks the PR and must be resolved before merge.
🧹 Nitpick comments (1)
packages/traceloop-sdk/src/lib/tracing/span-processor.ts (1)
27-35: Consider adding a size limit to prevent unbounded memory growth.The
traceAgentNamesmap has no maximum size limit. In high-volume production environments with many concurrent traces, this could lead to memory issues even with TTL-based cleanup. Consider adding a size threshold (e.g., 1000 entries) and an eviction strategy (LRU or FIFO) when the limit is reached.Example approach:
const traceAgentNames = new Map< string, { agentName: string; timestamp: number } >(); +const MAX_TRACE_AGENT_NAMES = 1000; + // TTL for trace agent names (5 minutes) const TRACE_AGENT_NAME_TTL = 5 * 60 * 1000;Then enforce the limit when adding entries:
// When storing agent name (in onSpanEnd) if (traceAgentNames.size >= MAX_TRACE_AGENT_NAMES) { // Remove oldest entry (first in iteration order for Map) const firstKey = traceAgentNames.keys().next().value; if (firstKey) traceAgentNames.delete(firstKey); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-propagate-agent-name-to-tool-call-spans_3577231859/recording.har(1 hunks)packages/traceloop-sdk/src/lib/tracing/span-processor.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Import AI/LLM semantic attribute constants from @traceloop/ai-semantic-conventions rather than hardcoding strings
Files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
packages/traceloop-sdk/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/traceloop-sdk/**/*.{ts,tsx}: Use the provided decorators (@workflow, @task, @agent) for workflow/task/agent spans instead of re-implementing them
For manual LLM operations, use trace.withLLMSpan from @traceloop/node-server-sdk
Files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
**/recordings/**
📄 CodeRabbit inference engine (CLAUDE.md)
Store HTTP interaction recordings for tests under recordings/ directories for Polly.js replay
Files:
packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-propagate-agent-name-to-tool-call-spans_3577231859/recording.har
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : For manual LLM operations, use trace.withLLMSpan from traceloop/node-server-sdk
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : Use the provided decorators (workflow, task, agent) for workflow/task/agent spans instead of re-implementing them
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/**/*.{ts,tsx} : For manual LLM operations, use trace.withLLMSpan from traceloop/node-server-sdk
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must create spans with appropriate AI/LLM semantic attributes for calls they wrap
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.tspackages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-propagate-agent-name-to-tool-call-spans_3577231859/recording.har
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/{instrumentation-*,traceloop-sdk}/**/*.{ts,tsx} : Import AI/LLM semantic attribute constants from traceloop/ai-semantic-conventions rather than hardcoding strings
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.tspackages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-propagate-agent-name-to-tool-call-spans_3577231859/recording.har
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/ai-semantic-conventions/src/SemanticAttributes.ts : Define all AI/LLM span attribute constants in packages/ai-semantic-conventions/src/SemanticAttributes.ts
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/traceloop-sdk/src/lib/node-server-sdk.ts : Register new instrumentation packages during SDK initialization
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Do not implement anonymous telemetry collection in instrumentation packages; telemetry is collected only in the SDK
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
📚 Learning: 2025-08-24T22:08:07.023Z
Learnt from: CR
Repo: traceloop/openllmetry-js PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-24T22:08:07.023Z
Learning: Applies to packages/instrumentation-*/**/*.{ts,tsx} : Instrumentations must extract request/response data and token usage from wrapped calls
Applied to files:
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build and test
🔇 Additional comments (4)
packages/traceloop-sdk/recordings/Test-AI-SDK-Agent-Integration-with-Recording_2039949225/should-propagate-agent-name-to-tool-call-spans_3577231859/recording.har (2)
1-172: Recording structure and security look good.The HAR recording structure is valid and appropriate for Polly.js test replay. No security concerns detected - no API keys or sensitive authentication data are exposed in the headers. The recording correctly captures a tool call scenario that aligns with the test name for propagating agent names to tool call spans.
Note: The agent metadata itself wouldn't appear in this OpenAI API recording, as it's handled at the AI SDK instrumentation/telemetry layer, not passed to the OpenAI API.
32-32: Recording correctly uses OpenAI's Responses API format—no changes needed.The Responses API uses
inputinstead ofmessages, and request bodies include input items with role and content fields. The Responses API is a superset of Chat Completions with additional features, so the format difference is expected. OpenAI released the Responses API in March 2025 as the successor to Chat Completions. The recording's endpoint and format are both correct for this API version.packages/traceloop-sdk/src/lib/tracing/span-processor.ts (2)
37-47: LGTM — Cleanup logic is correct.The TTL-based cleanup implementation correctly removes expired entries. However, note that this function's effectiveness depends entirely on how frequently it's called. The probabilistic invocation (1% per span at line 293) may be insufficient in both low-volume (rarely runs) and high-volume (accumulation between cleanups) scenarios.
Consider whether deterministic cleanup (e.g., setInterval or size-threshold-triggered) would be more reliable:
// Example: Run cleanup on a fixed interval let cleanupInterval: NodeJS.Timeout | null = null; export const startCleanupInterval = () => { if (!cleanupInterval) { cleanupInterval = setInterval(cleanupExpiredTraceAgentNames, 60000); // Every minute } };
49-59: Root span detection logic is correct and follows OpenTelemetry standards.The implementation correctly identifies root spans. The pattern of checking
parentSpanContext.spanId === "0000000000000000"is the canonical approach used by OpenTelemetry Collector and aligns with OT specifications where root spans have an all-zero span ID. The defensive checks (!parentContextand!parentContext.spanId) provide safe guards before the ID comparison. This logic works correctly across OpenTelemetry SDK versions.
Summary
Adds automatic agent detection when using Vercel AI SDK with agent metadata, following the Python OpenLLMetry reference implementation.
Changes
transformTelemetryMetadata(): Auto-detectsagentmetadata keytraceloop.span.kind: "agent"when detectedgen_ai.agent.nameattributetraceloop.association.properties.*Example Usage
Resulting Attributes
{ "gen_ai.agent.name": "research_assistant", "traceloop.span.kind": "agent", "traceloop.association.properties.agent": "research_assistant", "traceloop.association.properties.sessionId": "session_123", "traceloop.association.properties.userId": "user_456" }Testing
All tests passing:
agentmetadata presentagentmetadata absentFiles Changed
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts(+15 lines)packages/traceloop-sdk/test/ai-sdk-transformations.test.ts(+53 lines)packages/sample-app/package.json(+2 lines)packages/sample-app/src/sample_vercel_ai_agent.ts(new file)packages/sample-app/src/sample_vercel_ai_agent_simple.ts(new file)Total: 5 files changed, 613 insertions(+)
Related
gen_ai.agent.nameattribute (added in #XXX by @galkleiman)🤖 Generated with Claude Code
Important
Adds agent detection to AI SDK, enhancing telemetry metadata transformation and span classification, with new tests and sample apps.
transformTelemetryMetadata()inai-sdk-transformations.tsto auto-detectagentmetadata key and setgen_ai.agent.nameattribute.traceloop.span.kind: "agent"for root AI spans whenagentmetadata is detected.traceloop.association.properties.*.span-processor.tsto propagate agent names across spans and clean up expired trace agent names.isRootSpan()andcleanupExpiredTraceAgentNames()functions.ai-sdk-agent-integration.test.tsto test agent name propagation and span behavior.ai-sdk-transformations.test.tswith tests for agent metadata handling.sample_vercel_ai_agent.tsandsample_vercel_ai_agent_simple.tsto demonstrate agent usage with session logging and telemetry.This description was created by
for 3440e2c. You can customize this summary. It will automatically update as commits are pushed.
Summary by CodeRabbit
New Features
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.