Skip to content

Conversation

@nina-kollman
Copy link
Contributor

@nina-kollman nina-kollman commented Dec 14, 2025

Important

Introduces an Associations API in the Traceloop SDK to manage and propagate trace associations, with comprehensive tests and refactoring for consistency.

  • New Features:
    • Introduces Associations class in associations.ts to manage trace associations with methods to set and propagate them.
    • Adds AssociationProperty enum for standard properties like CUSTOMER_ID, USER_ID, and SESSION_ID.
  • Refactor:
    • Renames ASSOCATION_PROPERTIES_KEY to ASSOCIATION_PROPERTIES_KEY in association.ts, decorators.ts, and span-processor.ts.
    • Makes associations.ts publicly available in node-server-sdk.ts.
  • Tests:
    • Adds comprehensive tests in associations.test.ts to validate setting, updating, and merging associations.
    • Validates propagation of associations to child spans and merging with withAssociationProperties().
  • Misc:
    • Updates ai-sdk-transformations.ts to remove unused ATTR_GEN_AI_CONVERSATION_ID logic.

This description was created by Ellipsis for a280997. You can customize this summary. It will automatically update as commits are pushed.


Summary by CodeRabbit

  • New Features

    • Associations API to link traces with conversation, customer, user, and session identifiers; interactive terminal chatbot with streaming responses, tools, and per-interaction summaries; example demos for conversation and customer-service flows.
  • Tests

    • Comprehensive test suite validating Associations behavior, merging, mid-flow updates, and propagation to child spans.
  • Chores

    • Added convenience run scripts for sample apps and included HTTP recordings used by tests.
  • Refactor

    • Renamed tracing key for consistency and made the associations module publicly available.
  • Dependencies

    • Added OpenTelemetry async context support runtime dependency.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 14, 2025

Note

Other AI code review bot(s) detected

CodeRabbit 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.

Walkthrough

Adds a new Associations API (types, set/merge behavior, span attribute mapping), fixes a context-key typo, exports the module, adds tests and HAR fixtures, updates span processing, introduces two sample chat apps and npm scripts, and adds an OpenTelemetry async-hooks dependency.

Changes

Cohort / File(s) Change Summary
NPM Scripts
packages/sample-app/package.json
Added run:associations and run:chatbot scripts to build and run sample apps.
Sample: Associations demo
packages/sample-app/src/sample_associations.ts
New module: ChatbotWithAssociations class, workflows/tasks demonstrating Associations.set, withAssociationProperties, multi-turn messaging and a customer-service demo; customerServiceDemo and main entrypoints.
Sample: Interactive Chatbot
packages/sample-app/src/sample_chatbot_interactive.ts
New terminal-based interactive chatbot with streaming GPT responses, tools (calculator/weather/time), per-interaction summaries, readline UI, and Traceloop association usage.
SDK: Associations module
packages/traceloop-sdk/src/lib/tracing/associations.ts
New module: AssociationProperty enum, STANDARD_ASSOCIATION_PROPERTIES, Association type, and Associations class with static set() to merge associations into OpenTelemetry context and set span attributes.
SDK: Context key rename & merges
packages/traceloop-sdk/src/lib/tracing/tracing.ts, packages/traceloop-sdk/src/lib/tracing/association.ts, packages/traceloop-sdk/src/lib/tracing/decorators.ts
Renamed export ASSOCATION_PROPERTIES_KEYASSOCIATION_PROPERTIES_KEY; updated imports/usages and merged existing association properties with new ones when setting context.
SDK: Span processing
packages/traceloop-sdk/src/lib/tracing/span-processor.ts
Import STANDARD_ASSOCIATION_PROPERTIES; set standard association attributes on spans without prefix and prefix custom properties; use corrected ASSOCIATION_PROPERTIES_KEY.
SDK: Public exports
packages/traceloop-sdk/src/lib/node-server-sdk.ts
Re-exported new associations module (export * from "./tracing/associations";).
SDK: Dependency
packages/traceloop-sdk/package.json
Added dependency @opentelemetry/context-async-hooks (^2.0.0).
Tests: Associations
packages/traceloop-sdk/test/associations.test.ts
Added comprehensive tests verifying association setting, merging, propagation to child spans, mid-workflow updates, and handling of all AssociationProperty types; uses Polly.js recordings and memory exporter assertions.
AI telemetry transform tests
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts, packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
Removed mapping and tests for ATTR_GEN_AI_CONVERSATION_ID derived from AI telemetry metadata (conversationId/sessionId).
Recordings / Fixtures
packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/.../*.har
Added multiple HAR files capturing HTTP interactions used by the association tests.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor User
    participant SampleApp as Sample App (Chatbot)
    participant Traceloop as Traceloop Associations
    participant ContextMgr as AsyncLocalStorage
    participant Span as OpenTelemetry Span
    participant OpenAI as OpenAI API

    User->>SampleApp: start workflow / send message
    SampleApp->>Traceloop: Associations.set(...) / withAssociationProperties(...)
    Traceloop->>ContextMgr: read existing association props
    ContextMgr-->>Traceloop: existing props
    Traceloop->>ContextMgr: merge props and enterWith(updatedContext)
    Traceloop->>Span: set span attributes (standard unprefixed, custom prefixed)
    SampleApp->>OpenAI: call chat completion (LLM span)
    OpenAI-->>SampleApp: stream assistant response
    SampleApp->>Traceloop: optionally update associations mid-workflow
    Traceloop->>ContextMgr: merge & propagate updated props
    Note right of Span: child spans inherit association attributes
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Focus areas:
    • packages/traceloop-sdk/src/lib/tracing/associations.ts — merging logic, use of AsyncLocalStorageContextManager.enterWith and async-context safety.
    • packages/traceloop-sdk/src/lib/tracing/span-processor.ts & association.ts — attribute naming (prefix vs unprefixed), context-key rename, and span-recording checks.
    • packages/traceloop-sdk/test/associations.test.ts and HAR fixtures — test reliability, Polly recordings, and span assertions.
    • Sample apps — streaming handling, OpenAI integration, and correct use of the new Associations API.

Poem

🐇 I hop through traces with keys held tight,

I stitch sessions, users, and chats by night.
Merged props nestle in context and span,
From prompt to reply I trace every plan.
Hooray — associations, stitched just right!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The PR title "fix(tracing): Add association property" is vague and generic, using broad terminology that doesn't clearly convey the primary change. The changeset introduces a comprehensive Associations API with merging, propagation, and multiple example implementations, but the title only mentions "Add association property" without specificity. Consider a more descriptive title such as "feat(tracing): Add Associations API with merge and propagation support" or "feat(tracing): Implement Associations API for managing trace properties" to better reflect the scope and primary intent of the changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch nk/chats

📜 Recent review details

Configuration used: defaults

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.

📥 Commits

Reviewing files that changed from the base of the PR and between d79c21b and a280997.

📒 Files selected for processing (1)
  • packages/traceloop-sdk/test/associations.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/associations.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/associations.test.ts
🧠 Learnings (3)
📚 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/associations.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/test/associations.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/test/associations.test.ts
🧬 Code graph analysis (1)
packages/traceloop-sdk/test/associations.test.ts (2)
packages/traceloop-sdk/test/test-setup.ts (2)
  • getSharedExporter (37-39)
  • initializeSharedTraceloop (23-35)
packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
  • SpanAttributes (17-58)
🔇 Additional comments (8)
packages/traceloop-sdk/test/associations.test.ts (8)

17-35: LGTM!

Imports correctly follow coding guidelines: SpanAttributes is imported from @traceloop/ai-semantic-conventions for Traceloop-specific constants, while ATTR_GEN_AI_PROMPT appropriately comes from @opentelemetry/semantic-conventions/incubating as a standard OpenTelemetry attribute. The shared exporter pattern is properly utilized.


40-82: LGTM!

Test setup follows best practices: dynamic OpenAI import after Polly setup ensures proper HTTP interception, authorization headers are correctly filtered from recordings to prevent credential leakage, and memory exporter reset between tests ensures proper isolation.


84-117: LGTM!

Test correctly validates single association propagation using withWorkflow as recommended. Assertions properly verify the association attribute on both workflow and LLM spans.


119-155: LGTM!

Good extension of the single association test, validating that multiple associations can be set simultaneously and are correctly propagated to all spans.


157-217: LGTM!

Excellent test case covering mid-workflow association updates. The approach of differentiating spans by prompt content is appropriate, and the assertions correctly verify that each span captures the association value at the time of span creation.


253-310: LGTM!

Excellent test for hierarchical span propagation. The use of withTask inside withWorkflow follows the coding guidelines for using SDK decorators, and the assertions comprehensively verify that associations propagate correctly through the entire span hierarchy.


312-359: LGTM!

Good test for the merge behavior between Associations.set() and withAssociationProperties(). The assertions correctly verify the distinction between standard properties (no prefix) and custom properties (with TRACELOOP_ASSOCIATION_PROPERTIES prefix), using the semantic convention constant as per coding guidelines.


219-251: No action needed - test coverage is complete.

The test correctly covers all AssociationProperty types defined in the SDK (CUSTOMER_ID, USER_ID, SESSION_ID). CONVERSATION_ID is not a standard AssociationProperty enum value; it's an example of a custom property that users can optionally set. The test title accurately reflects the complete coverage of all available enum values.

Likely an incorrect or invalid review comment.


Comment @coderabbitai help to get the list of available commands and usage tips.

@nina-kollman nina-kollman marked this pull request as ready for review December 21, 2025 08:32
Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a 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 everything up to 0bd19e0 in 1 minute and 49 seconds. Click for details.
  • Reviewed 2829 lines of code in 15 files
  • Skipped 1 files when reviewing.
  • Skipped posting 7 draft 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/node-server-sdk.ts:67
  • Draft comment:
    Exporting the associations module here cleanly exposes the Associations API. Ensure that its public API is well documented for users.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
2. packages/traceloop-sdk/src/lib/tracing/associations.ts:70
  • Draft comment:
    Accessing the private method _getContextManager via casting to 'any' is a bit hacky; consider using a public API for context management if available, or add a comment explaining why this approach is needed.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% The comment suggests using a public API or adding a comment explaining why this approach is needed. However, there ARE already comments in the code (lines 68-69 and 75) explaining why this approach is taken. The comment on line 69 explicitly states this is replicating Python's attach behavior, and line 75 explains the need for internal access. The automated tool's suggestion to "add a comment explaining why this approach is needed" is already satisfied. The suggestion to "use a public API if available" is speculative - it assumes there might be a better way without providing evidence that one exists. This violates the rule about not making speculative comments. Perhaps the existing comments aren't detailed enough, and the reviewer's suggestion could prompt the author to add more explanation about why no public API exists for this use case. The comment might also encourage the author to research if there's a better approach they missed. The rules explicitly state not to ask the author to confirm, double-check, or ensure things. Suggesting they "consider using a public API if available" is essentially asking them to verify they chose the right approach. The code already has explanatory comments, so the suggestion to add comments is already addressed. This is speculative and not actionable. The comment should be deleted because: 1) It suggests adding explanatory comments, but comments already exist explaining the approach, 2) It speculatively suggests using a public API "if available" without evidence one exists, which violates the rule against speculative comments, and 3) It's essentially asking the author to verify their approach, which the rules prohibit.
3. packages/traceloop-sdk/src/lib/tracing/span-processor.ts:302
  • Draft comment:
    The use of a random condition (Math.random() < 0.01) for cleanup of span agent names may lead to unpredictable cleanup timing. Consider using a dedicated periodic cleanup or a more deterministic strategy.
  • 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.
4. packages/traceloop-sdk/src/lib/tracing/association.ts:17
  • Draft comment:
    The merging of associations using the context API is clear and concise. No issues detected, but ensure that edge cases (e.g. empty properties) are handled as expected.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
5. packages/traceloop-sdk/test/associations.test.ts:80
  • Draft comment:
    The tests comprehensively cover single and multiple associations, as well as updates and propagation across child spans. Ensure that test recordings remain in sync with the current implementation.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
6. packages/traceloop-sdk/src/lib/tracing/association.ts:20
  • Draft comment:
    Typo: Consider correcting 'ASSOCATION_PROPERTIES_KEY' to 'ASSOCIATION_PROPERTIES_KEY'.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% The typo exists in the constant name 'ASSOCATION_PROPERTIES_KEY', but this constant is imported from another file (line 2: import { ASSOCATION_PROPERTIES_KEY } from "./tracing";). The diff shows that the code on lines 20 and 27 uses this constant, and line 20 is part of the new code added in this PR. However, to fix this typo, the constant would need to be renamed in the file where it's defined ("./tracing"), not in this file. The comment is placed on line 20, which is new code in the diff, so it is technically about changes. But the fix would require changes in another file (the import source), not just this file. According to the rules, I should "Ignore cross-file issues. Only think about the file you are reviewing." While the typo is real and the line is part of the diff, fixing it would require changing the constant definition in another file and updating the import, making this a cross-file issue. However, one could argue that the comment is still useful as it identifies a legitimate issue that should be addressed, even if it spans multiple files. The rules explicitly state to "Ignore cross-file issues. Only think about the file you are reviewing." Since fixing this typo would require changes to the constant definition in "./tracing" file and potentially other files that use it, this is clearly a cross-file issue and should be deleted according to the guidelines. This comment should be deleted because fixing the typo would require changes across multiple files (the constant definition in "./tracing" and all its usages), making it a cross-file issue which the rules explicitly say to ignore.
7. packages/traceloop-sdk/src/lib/tracing/association.ts:27
  • Draft comment:
    Typo: Consider correcting 'ASSOCATION_PROPERTIES_KEY' to 'ASSOCIATION_PROPERTIES_KEY'.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% The typo exists in the constant name 'ASSOCATION_PROPERTIES_KEY', but this constant is imported from another file (line 2: import { ASSOCATION_PROPERTIES_KEY } from "./tracing";). The diff shows that the code on lines 20 and 27 uses this constant, and line 20 is part of the new code added in this PR. However, to fix this typo, the constant would need to be renamed in the file where it's defined ("./tracing"), not in this file. The comment is placed on line 20, which is new code in the diff, so it is technically about changes. But the fix would require changes in another file (the import source), not just this file. According to the rules, I should "Ignore cross-file issues. Only think about the file you are reviewing." While the typo is real and the line is part of the diff, fixing it would require changing the constant definition in another file and updating the import, making this a cross-file issue. However, one could argue that the comment is still useful as it identifies a legitimate issue that should be addressed, even if it spans multiple files. The rules explicitly state to "Ignore cross-file issues. Only think about the file you are reviewing." Since fixing this typo would require changes to the constant definition in "./tracing" file and potentially other files that use it, this is clearly a cross-file issue and should be deleted according to the guidelines. This comment should be deleted because fixing the typo would require changes across multiple files (the constant definition in "./tracing" and all its usages), making it a cross-file issue which the rules explicitly say to ignore.

Workflow ID: wflow_azCfKvpt7WYGGzwu

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (1)
packages/sample-app/src/sample_chatbot_interactive.ts (1)

117-129: Consider replacing eval() with a safer math parser.

While the expression is sanitized to allow only numbers and operators, eval() remains risky and is flagged by static analysis tools. For a demo app this is acceptable, but for production use, consider a dedicated math expression parser like mathjs or expr-eval.

🔎 Safer alternative using a math library
+import { evaluate } from 'mathjs';
+
 execute: async ({ expression }) => {
   try {
-    // Simple safe eval for basic math (only allow numbers and operators)
-    const sanitized = expression.replace(/[^0-9+\-*/().\s]/g, "");
-    const result = eval(sanitized);
+    // Use mathjs for safe expression evaluation
+    const result = evaluate(expression);
     console.log(
       `\n${colors.yellow}🔧 Calculator: ${expression} = ${result}${colors.reset}`,
     );
     return { result, expression };
   } catch (error) {
     return { error: "Invalid mathematical expression" };
   }
 },
📜 Review details

Configuration used: defaults

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.

📥 Commits

Reviewing files that changed from the base of the PR and between f480743 and 0bd19e0.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (15)
  • packages/sample-app/package.json (2 hunks)
  • packages/sample-app/src/sample_associations.ts (1 hunks)
  • packages/sample-app/src/sample_chatbot_interactive.ts (1 hunks)
  • packages/traceloop-sdk/package.json (1 hunks)
  • packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-allow-updating-associations-mid-workflow_3438992191/recording.har (1 hunks)
  • packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-merge-associations-from-Associations-set-and-withAssociationProperties_2272111199/recording.har (1 hunks)
  • packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-propagate-associations-to-all-child-spans_3781439892/recording.har (1 hunks)
  • packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-set-multiple-associations-on-spans_3842784822/recording.har (1 hunks)
  • packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-set-single-association-on-spans_3887215347/recording.har (1 hunks)
  • packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-work-with-all-AssociationProperty-types_111443069/recording.har (1 hunks)
  • packages/traceloop-sdk/src/lib/node-server-sdk.ts (1 hunks)
  • packages/traceloop-sdk/src/lib/tracing/association.ts (1 hunks)
  • packages/traceloop-sdk/src/lib/tracing/associations.ts (1 hunks)
  • packages/traceloop-sdk/src/lib/tracing/span-processor.ts (2 hunks)
  • packages/traceloop-sdk/test/associations.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/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-Associations-API_2277442331/should-work-with-all-AssociationProperty-types_111443069/recording.har
  • packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-allow-updating-associations-mid-workflow_3438992191/recording.har
  • packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-propagate-associations-to-all-child-spans_3781439892/recording.har
  • packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-merge-associations-from-Associations-set-and-withAssociationProperties_2272111199/recording.har
  • packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-set-multiple-associations-on-spans_3842784822/recording.har
  • packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-set-single-association-on-spans_3887215347/recording.har
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/src/lib/tracing/associations.ts
  • packages/traceloop-sdk/src/lib/tracing/association.ts
  • packages/traceloop-sdk/test/associations.test.ts
  • packages/traceloop-sdk/src/lib/node-server-sdk.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
  • packages/traceloop-sdk/src/lib/tracing/associations.ts
  • packages/traceloop-sdk/src/lib/tracing/association.ts
  • packages/traceloop-sdk/test/associations.test.ts
  • packages/traceloop-sdk/src/lib/node-server-sdk.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
  • 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/traceloop-sdk/src/lib/node-server-sdk.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Register new instrumentation packages during SDK initialization

Files:

  • packages/traceloop-sdk/src/lib/node-server-sdk.ts
🧠 Learnings (7)
📚 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
  • packages/traceloop-sdk/src/lib/tracing/associations.ts
  • packages/traceloop-sdk/package.json
  • packages/sample-app/src/sample_associations.ts
  • packages/traceloop-sdk/src/lib/node-server-sdk.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
  • packages/traceloop-sdk/src/lib/tracing/associations.ts
  • packages/traceloop-sdk/test/associations.test.ts
  • packages/traceloop-sdk/package.json
  • packages/sample-app/src/sample_chatbot_interactive.ts
  • packages/sample-app/src/sample_associations.ts
  • packages/traceloop-sdk/src/lib/node-server-sdk.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
  • packages/traceloop-sdk/src/lib/tracing/associations.ts
  • packages/traceloop-sdk/test/associations.test.ts
  • packages/traceloop-sdk/package.json
  • packages/traceloop-sdk/src/lib/node-server-sdk.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/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
  • packages/traceloop-sdk/src/lib/tracing/associations.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/package.json : When adding a new instrumentation package, add it to the main SDK dependencies

Applied to files:

  • packages/traceloop-sdk/package.json
  • packages/traceloop-sdk/src/lib/node-server-sdk.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.json
  • packages/traceloop-sdk/src/lib/node-server-sdk.ts
🧬 Code graph analysis (3)
packages/traceloop-sdk/src/lib/tracing/span-processor.ts (2)
packages/traceloop-sdk/src/lib/tracing/associations.ts (1)
  • STANDARD_ASSOCIATION_PROPERTIES (19-21)
packages/ai-semantic-conventions/src/SemanticAttributes.ts (1)
  • SpanAttributes (17-58)
packages/traceloop-sdk/src/lib/tracing/association.ts (1)
packages/traceloop-sdk/src/lib/tracing/tracing.ts (1)
  • ASSOCATION_PROPERTIES_KEY (7-9)
packages/sample-app/src/sample_chatbot_interactive.ts (1)
packages/traceloop-sdk/src/lib/tracing/decorators.ts (1)
  • tool (287-293)
🪛 Biome (2.1.2)
packages/sample-app/src/sample_chatbot_interactive.ts

[error] 121-121: eval() exposes to security risks and performance issues.

See the MDN web docs for more details.
Refactor the code so that it doesn't need to call eval().

(lint/security/noGlobalEval)

🔇 Additional comments (23)
packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-allow-updating-associations-mid-workflow_3438992191/recording.har (1)

1-490: Valid HAR recording for Polly.js test replay.

The file is a well-formed HAR 1.2 recording that captures the mid-workflow associations update scenario: two sequential OpenAI chat completions requests demonstrating association changes between calls. The structure, metadata (startedDateTime, timings), base64-encoded responses, and Polly.js naming conventions are all correct.

packages/sample-app/package.json (1)

18-18: LGTM!

The new demo scripts follow the established pattern and provide convenient entry points for showcasing the associations API and interactive chatbot functionality.

Also applies to: 47-47

packages/traceloop-sdk/src/lib/node-server-sdk.ts (1)

67-67: LGTM!

The export follows the established pattern and correctly exposes the new associations API as part of the SDK's public surface.

packages/traceloop-sdk/src/lib/tracing/span-processor.ts (2)

18-18: LGTM!

The import correctly brings in the standard association properties set for distinguishing standard from custom properties.


204-213: LGTM!

The conditional logic correctly distinguishes between standard and custom association properties. Standard properties (conversation_id, customer_id, user_id, session_id) are set directly on spans for better discoverability, while custom properties retain the namespace prefix to avoid conflicts.

packages/traceloop-sdk/src/lib/tracing/association.ts (1)

17-27: LGTM! Note the merge semantics.

The new merging logic correctly accumulates association properties across nested calls. The spread operator semantics mean that new properties override existing ones with the same key, which appears intentional for allowing updates to associations mid-workflow.

packages/traceloop-sdk/package.json (1)

60-60: The @opentelemetry/context-async-hooks dependency is used in the codebase. It is imported to instantiate AsyncLocalStorageContextManager for context propagation in packages/traceloop-sdk/src/lib/tracing/associations.ts.

packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-propagate-associations-to-all-child-spans_3781439892/recording.har (1)

1-252: LGTM!

This HAR recording follows the expected Polly.js format and is correctly placed under the recordings/ directory as per coding guidelines. Authorization headers are properly filtered out.

packages/traceloop-sdk/recordings/Test-Associations-API_2277442331/should-merge-associations-from-Associations-set-and-withAssociationProperties_2272111199/recording.har (1)

1-252: LGTM!

This HAR recording is properly structured for the merge associations test case, with authorization headers correctly filtered.

packages/traceloop-sdk/test/associations.test.ts (3)

17-36: LGTM!

Good use of SpanAttributes from @traceloop/ai-semantic-conventions as per coding guidelines. The shared test setup approach prevents conflicts with other test suites.


40-82: LGTM!

The test setup properly handles recording vs replay modes, filters authorization headers from recordings to prevent secrets leakage, and resets the memory exporter between tests for isolation.


84-367: LGTM!

Comprehensive test coverage for the Associations API including:

  • Single and multiple association setting
  • Mid-workflow updates
  • All property types
  • Child span propagation
  • Merging standard associations with custom properties via withAssociationProperties

The tests correctly verify that standard properties appear without prefix while custom properties use the TRACELOOP_ASSOCIATION_PROPERTIES prefix.

packages/traceloop-sdk/src/lib/tracing/associations.ts (2)

5-26: LGTM!

Clean API design with the AssociationProperty enum providing type safety, and STANDARD_ASSOCIATION_PROPERTIES enabling O(1) lookup for distinguishing standard from custom properties.


82-88: LGTM!

Correctly sets standard association properties directly on the span without a prefix, with a proper isRecording() guard.

packages/sample-app/src/sample_associations.ts (4)

1-12: LGTM!

Clean initialization with the Traceloop SDK and OpenAI client. Using environment variable for the API key is a good practice.


18-87: LGTM!

Good demonstration of the Associations API using the @workflow and @task decorators as per coding guidelines. The combination of Associations.set() for standard properties and withAssociationProperties() for custom properties is clearly illustrated.


89-141: LGTM!

Good demonstration of updating associations mid-workflow to track different customers and agents within the same workflow context.


143-178: LGTM!

Clean main function with proper error handling and helpful console output guiding users to check the Traceloop dashboard.

packages/sample-app/src/sample_chatbot_interactive.ts (5)

1-25: LGTM!

Clean imports and initialization. Using Zod for tool parameter validation is a good practice.


38-41: Acceptable for demo purposes.

Using Date.now() and Math.random() for generating demo conversation/user IDs is fine for a sample application. These are not used in any security-sensitive context—they're purely for tracing identification in a demo scenario.


43-77: LGTM!

Good use of the @task decorator as per coding guidelines. The streaming summary generation with GPT-4o-mini is appropriate for creating brief interaction titles.


218-276: LGTM!

Clean implementation of the interactive CLI with proper command handling (/exit, /clear), error handling around message processing, and cleanup on close.


279-284: LGTM!

Clean main entry point with error handling.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a 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 36c7cb2 in 36 seconds. Click for details.
  • Reviewed 114 lines of code in 5 files
  • Skipped 0 files when reviewing.
  • Skipped posting 9 draft 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/association.ts:2
  • Draft comment:
    Fixed constant spelling: using ASSOCIATION_PROPERTIES_KEY consistently.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is purely informative, as it only states that a constant spelling was fixed and used consistently. It doesn't provide any actionable feedback or suggestions for improvement.
2. packages/traceloop-sdk/src/lib/tracing/associations.ts:3
  • Draft comment:
    Renamed ASSOCATION_PROPERTIES_KEY to ASSOCIATION_PROPERTIES_KEY for consistency.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is purely informative, as it only states that a variable was renamed for consistency. It does not provide a suggestion, ask for confirmation, or highlight a potential issue.
3. packages/traceloop-sdk/src/lib/tracing/decorators.ts:5
  • Draft comment:
    Updated decorators to use the corrected ASSOCIATION_PROPERTIES_KEY.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is purely informative, stating what was done without providing any actionable feedback or suggestions. It doesn't ask for confirmation or suggest improvements, nor does it point out any potential issues. Therefore, it should be removed according to the rules.
4. packages/traceloop-sdk/src/lib/tracing/span-processor.ts:12
  • Draft comment:
    Correct constant name used when retrieving association properties from context.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment seems to be purely informative, as it is just stating that the correct constant name is used. It doesn't provide any actionable feedback or suggestions for improvement.
5. packages/traceloop-sdk/src/lib/tracing/tracing.ts:7
  • Draft comment:
    Defined ASSOCIATION_PROPERTIES_KEY with corrected spelling.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is purely informative, as it only states that a variable was defined with corrected spelling. It does not provide any actionable feedback or suggestions for improvement.
6. packages/traceloop-sdk/src/lib/tracing/associations.ts:3
  • Draft comment:
    Typo fixed: Corrected 'ASSOCATION_PROPERTIES_KEY' to 'ASSOCIATION_PROPERTIES_KEY'.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is purely informative as it only states that a typo was fixed. It does not provide any actionable feedback or suggestions for improvement.
7. packages/traceloop-sdk/src/lib/tracing/associations.ts:51
  • Draft comment:
    Typographical error fixed: The constant was previously spelled as ASSOCATION_PROPERTIES_KEY and has been corrected to ASSOCIATION_PROPERTIES_KEY.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is purely informative, pointing out a typographical correction. It doesn't provide a suggestion or ask for confirmation on a specific code change. According to the rules, purely informative comments should be removed.
8. packages/traceloop-sdk/src/lib/tracing/decorators.ts:74
  • Draft comment:
    Typographical error fixed: changed 'ASSOCATION_PROPERTIES_KEY' to 'ASSOCIATION_PROPERTIES_KEY'. Good catch!
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is purely informative, as it only states that a typographical error was fixed. It does not provide any actionable feedback or suggestions for improvement.
9. packages/traceloop-sdk/src/lib/tracing/span-processor.ts:12
  • Draft comment:
    Typo corrected: Changed ASSOCATION_PROPERTIES_KEY to ASSOCIATION_PROPERTIES_KEY to fix the spelling error.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is purely informative, as it only states that a typo was corrected. It does not provide any actionable feedback or suggestions for improvement.

Workflow ID: wflow_qu4YoiBlrTXcTUQU

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a 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 d79c21b in 53 seconds. Click for details.
  • Reviewed 317 lines of code in 6 files
  • Skipped 0 files when reviewing.
  • Skipped posting 5 draft 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/test/associations.test.ts:37
  • Draft comment:
    The tests comprehensively cover association propagation (single, multiple, update, child spans) and merging. Consider also adding edge cases for invalid or unexpected association values.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
2. packages/traceloop-sdk/test/associations.test.ts:318
  • Draft comment:
    The merge test (using Associations.set() with withAssociationProperties()) clearly validates that both standard and custom properties are propagated properly.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
3. packages/traceloop-sdk/test/associations.test.ts:254
  • Draft comment:
    Child span propagation is well-tested using withTask in combination with withWorkflow. This confirms that associations set at the parent level properly propagate to nested spans.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
4. packages/traceloop-sdk/test/associations.test.ts:157
  • Draft comment:
    The updating associations mid-workflow test effectively simulates real-world dynamic association changes and verifies expected behavior.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
5. packages/traceloop-sdk/test/associations.test.ts:367
  • Draft comment:
    Overall, the test structure is robust—using Polly for HTTP interception and a memoryExporter reset in afterEach ensures isolation across tests. The assertions correctly verify that association properties (customer_id, user_id, session_id) are set as expected.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None

Workflow ID: wflow_DBOjOHCTMjmA7Rnw

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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/sample-app/src/sample_chatbot_interactive.ts (1)

38-40: Consider using crypto.randomUUID() for session/user IDs.

The current approach using Math.random() was flagged by security scanning. While acceptable for a sample app, using crypto.randomUUID() provides proper uniqueness guarantees and is equally simple.

🔎 Proposed fix
+import { randomUUID } from "crypto";
+
 constructor() {
   this.rl = readline.createInterface({
     input: process.stdin,
     output: process.stdout,
     prompt: `${colors.cyan}${colors.bright}You: ${colors.reset}`,
   });
   // Generate unique IDs for this session
-  this.sessionId = `session-${Date.now()}`;
-  this.userId = `user-${Math.random().toString(36).substring(7)}`;
+  this.sessionId = `session-${randomUUID()}`;
+  this.userId = `user-${randomUUID()}`;
 }
packages/traceloop-sdk/src/lib/tracing/associations.ts (1)

67-79: Private OpenTelemetry API access requires documentation and fallback handling.

This issue was already flagged in a previous review. The code accesses undocumented internal APIs (_getContextManager() and _asyncLocalStorage) which may break across OpenTelemetry versions. Additionally, if the context manager is not AsyncLocalStorageContextManager, associations silently fail to propagate.

Consider adding:

  1. A comment documenting this as a Node.js-only workaround
  2. Warning-level logging when the expected context manager is not found
  3. Documentation of minimum OpenTelemetry version requirements
📜 Review details

Configuration used: defaults

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.

📥 Commits

Reviewing files that changed from the base of the PR and between 36c7cb2 and d79c21b.

📒 Files selected for processing (6)
  • packages/sample-app/src/sample_associations.ts (1 hunks)
  • packages/sample-app/src/sample_chatbot_interactive.ts (1 hunks)
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts (0 hunks)
  • packages/traceloop-sdk/src/lib/tracing/associations.ts (1 hunks)
  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts (0 hunks)
  • packages/traceloop-sdk/test/associations.test.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
  • packages/traceloop-sdk/test/ai-sdk-transformations.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/traceloop-sdk/test/associations.test.ts
  • packages/sample-app/src/sample_associations.ts
🧰 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/associations.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/associations.ts
🧠 Learnings (5)
📓 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/traceloop-sdk/**/*.{ts,tsx} : For manual LLM operations, use trace.withLLMSpan from traceloop/node-server-sdk
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/traceloop-sdk/package.json : When adding a new instrumentation package, add it to the main SDK dependencies
📚 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/associations.ts
  • packages/sample-app/src/sample_chatbot_interactive.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/associations.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/associations.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/associations.ts
🧬 Code graph analysis (1)
packages/sample-app/src/sample_chatbot_interactive.ts (1)
packages/traceloop-sdk/src/lib/tracing/decorators.ts (1)
  • tool (287-293)
🪛 Biome (2.1.2)
packages/sample-app/src/sample_chatbot_interactive.ts

[error] 121-121: eval() exposes to security risks and performance issues.

See the MDN web docs for more details.
Refactor the code so that it doesn't need to call eval().

(lint/security/noGlobalEval)

⏰ 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/src/lib/tracing/associations.ts (2)

8-12: Missing CONVERSATION_ID from the enum.

The PR objectives mention support for CONVERSATION_ID, but the AssociationProperty enum only includes CUSTOMER_ID, USER_ID, and SESSION_ID. If this is intentional, please update the PR description; otherwise, add the missing property.

🔎 Proposed fix to add CONVERSATION_ID
 export enum AssociationProperty {
+  CONVERSATION_ID = "conversation_id",
   CUSTOMER_ID = "customer_id",
   USER_ID = "user_id",
   SESSION_ID = "session_id",
 }

46-88: Implementation correctly merges and propagates associations.

The logic for retrieving existing associations, merging new values, updating the context, and setting span attributes is well-structured. The use of spread operator for immutable copy is appropriate.

packages/sample-app/src/sample_chatbot_interactive.ts (2)

43-77: Good use of Traceloop decorators and Associations API.

The implementation correctly uses @traceloop.workflow and @traceloop.task decorators as per the SDK guidelines, and properly demonstrates the new Associations.set() API with AssociationProperty enum values.

Also applies to: 79-86


225-276: Solid interactive CLI implementation with proper cleanup.

The readline handling includes appropriate command processing (/exit, /clear), error handling for message processing, and graceful shutdown on close events.

Comment on lines +117 to +129
execute: async ({ expression }) => {
try {
// Simple safe eval for basic math (only allow numbers and operators)
const sanitized = expression.replace(/[^0-9+\-*/().\s]/g, "");
const result = eval(sanitized);
console.log(
`\n${colors.yellow}🔧 Calculator: ${expression} = ${result}${colors.reset}`,
);
return { result, expression };
} catch (error) {
return { error: "Invalid mathematical expression" };
}
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Replace eval() with a safe math expression parser.

Even with character sanitization, eval() poses security risks and is flagged by static analysis. The regex sanitization allows operators that could still be exploited or cause unexpected behavior (e.g., empty expressions, division by zero edge cases).

Consider using a library like mathjs or expr-eval for safe expression evaluation.

🔎 Proposed fix using expr-eval

First, add the dependency:

npm install expr-eval

Then update the code:

+import { Parser } from "expr-eval";
+
+const mathParser = new Parser();
+
 calculator: tool({
   description:
     "Perform mathematical calculations. Supports basic arithmetic operations.",
   parameters: z.object({
     expression: z
       .string()
       .describe(
         "The mathematical expression to evaluate (e.g., '2 + 2' or '10 * 5')",
       ),
   }),
   execute: async ({ expression }) => {
     try {
-      // Simple safe eval for basic math (only allow numbers and operators)
-      const sanitized = expression.replace(/[^0-9+\-*/().\s]/g, "");
-      const result = eval(sanitized);
+      const result = mathParser.evaluate(expression);
       console.log(
         `\n${colors.yellow}🔧 Calculator: ${expression} = ${result}${colors.reset}`,
       );
       return { result, expression };
     } catch (error) {
       return { error: "Invalid mathematical expression" };
     }
   },
 }),

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Biome (2.1.2)

[error] 121-121: eval() exposes to security risks and performance issues.

See the MDN web docs for more details.
Refactor the code so that it doesn't need to call eval().

(lint/security/noGlobalEval)

🤖 Prompt for AI Agents
In packages/sample-app/src/sample_chatbot_interactive.ts around lines 117-129,
replace the unsafe eval-based math evaluation with a safe expression parser
(e.g., expr-eval): add the dependency (npm install expr-eval), import Parser
from 'expr-eval', validate the incoming expression is non-empty, parse and
evaluate using Parser.parse(expression).evaluate(), catch parse/eval errors and
return a clear "Invalid mathematical expression" error, and handle edge cases
like division by zero by detecting Infinity/NaN results and returning an error
instead of logging them; keep the same console output format when returning a
valid result.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a 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 a280997 in 39 seconds. Click for details.
  • Reviewed 23 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 2 draft 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/test/associations.test.ts:302
  • Draft comment:
    Reformatted assert.strictEqual for taskSpan to a single line for consistency.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
2. packages/traceloop-sdk/test/associations.test.ts:308
  • Draft comment:
    Reformatted assert.strictEqual for chatSpan to a single line for consistency.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None

Workflow ID: wflow_At3u4LyEDWEJ80Ri

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants