-
Notifications
You must be signed in to change notification settings - Fork 859
feat(tracing): Add general AssociationProperty #3484
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
|
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 an associations mechanism to the Traceloop SDK (context storage and span attribute propagation), integrates it into the SDK client and span processing, and introduces a sample Gemini chatbot demonstrating Traceloop observability and tool-driven assistant flows. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User
participant ChatbotApp as "Gemini Chatbot"
participant Gemini as "Gemini GenAI Client"
participant Tool as "Tool (weather/time/knowledge)"
participant Traceloop as "Traceloop (Client/Associations)"
participant SpanProc as "Span Processor (on_start)"
Note over User,ChatbotApp: Interactive chat starts
User->>ChatbotApp: send user_message
ChatbotApp->>Traceloop: Associations.set(...) (stores in context)
ChatbotApp->>Gemini: request generation (with tool schema)
Gemini-->>ChatbotApp: requests tool call (function name + args)
ChatbotApp->>Tool: execute_function(function_name, args)
Tool-->>ChatbotApp: tool result (simulated)
ChatbotApp->>Gemini: provide tool result
Gemini-->>ChatbotApp: assistant textual response
ChatbotApp->>SpanProc: span start triggers
SpanProc->>SpanProc: read associations from context
SpanProc->>SpanProc: set span attributes for each association
ChatbotApp-->>User: return assistant response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Poem
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 a7ae838 in 37 seconds. Click for details.
- Reviewed
235lines 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/sample-app/sample_app/gemini_chatbot_with_tools.py:1
- Draft comment:
The entire file is being deleted. The PR title mentions adding a 'conversation_id' attribute to span attributes, but the diff removes a sample file that used 'chat_id'. Please verify if this deletion was intentional and that the intended changes (i.e. adding 'conversation_id') are applied in the correct location. - 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_2vwhVXTQV0RtiWcn
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.
Important
Looks good to me! 👍
Reviewed everything up to cd37f9a in 2 minutes and 11 seconds. Click for details.
- Reviewed
586lines of code in5files - Skipped
0files 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/sample-app/sample_app/chats/gemini_chatbot.py:128
- Draft comment:
Good use of Traceloop.set_conversation_id to attach the conversation identifier to spans. This ensures observability for each conversation. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
2. packages/sample-app/sample_app/gemini_chatbot_with_tools.py:128
- Draft comment:
Consider using 'conversation_id' instead of 'chat_id' for consistency. Currently, the attribute is set as 'chat_id' while tests and other modules use 'conversation_id'. - 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% This comment is making a claim about consistency with other parts of the codebase (tests and other modules) that I cannot verify from the diff. The rules explicitly state "Ignore cross-file issues. Only think about the file you are reviewing." This is clearly a cross-file consistency issue. Additionally, since this is a new file, there's no "change" being made to an existing naming convention - the author chosechat_idfrom the start. The comment would require me to look at other files to verify ifconversation_idis indeed the standard, which violates the review guidelines. Could the comment be valid if there's a clear codebase-wide convention that should be followed? Perhaps the automated tool has access to the full codebase and identified a legitimate inconsistency that would cause confusion or integration issues. Even if there is a codebase-wide convention, the rules explicitly state to ignore cross-file issues and only focus on the file being reviewed. Without being able to see the other files mentioned (tests and other modules), I cannot verify this claim, and per the instructions, I should delete comments that require more context from other files. The most important rule is that I need STRONG EVIDENCE the comment is correct, and I don't have that evidence in this diff. This comment should be deleted because it's a cross-file consistency issue that cannot be verified from the diff alone. The rules explicitly state to ignore cross-file issues and only review the file at hand. Without access to the tests and other modules mentioned, there's no strong evidence this comment is correct.
3. packages/traceloop-sdk/tests/test_conversation_id.py:15
- Draft comment:
Tests for conversation_id propagation look comprehensive and validate that conversation_id is correctly applied to both workflow and task spans. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
4. packages/traceloop-sdk/traceloop/sdk/__init__.py:206
- Draft comment:
The new static method set_conversation_id properly delegates to the underlying tracing function, ensuring central handling of the conversation id. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
5. packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py:245
- Draft comment:
The set_conversation_id function attaches the conversation_id to the current span as intended. Ensure that the attribute name 'conversation_id' is used uniformly across all modules. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
Workflow ID: wflow_XPhRxGaTkLPG9bKW
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
🧹 Nitpick comments (1)
packages/sample-app/sample_app/chats/gemini_chatbot.py (1)
215-222: Broad exception handling is acceptable for sample code.While the static analysis tool flags the broad
Exceptioncatch, this is reasonable for a sample CLI application where preventing crashes and providing a good user experience is prioritized over granular error handling.For production code, consider catching more specific exceptions (e.g., API-related errors, network errors).
📜 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 (4)
packages/sample-app/sample_app/chats/gemini_chatbot.py(1 hunks)packages/traceloop-sdk/tests/test_conversation_id.py(1 hunks)packages/traceloop-sdk/traceloop/sdk/__init__.py(2 hunks)packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py(2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Store API keys only in environment variables/secure vaults; never hardcode secrets in code
Use Flake8 for code linting and adhere to its rules
Files:
packages/traceloop-sdk/traceloop/sdk/__init__.pypackages/sample-app/sample_app/chats/gemini_chatbot.pypackages/traceloop-sdk/tests/test_conversation_id.pypackages/traceloop-sdk/traceloop/sdk/tracing/tracing.py
🧬 Code graph analysis (3)
packages/traceloop-sdk/traceloop/sdk/__init__.py (1)
packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py (1)
set_conversation_id(245-252)
packages/traceloop-sdk/tests/test_conversation_id.py (2)
packages/traceloop-sdk/traceloop/sdk/__init__.py (1)
Traceloop(37-272)packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py (1)
set_conversation_id(245-252)
packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py (1)
packages/traceloop-sdk/traceloop/sdk/__init__.py (1)
set_conversation_id(206-207)
🪛 Ruff (0.14.6)
packages/sample-app/sample_app/chats/gemini_chatbot.py
220-220: Do not catch blind exception: Exception
(BLE001)
⏰ 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). (5)
- GitHub Check: Test Packages (3.12)
- GitHub Check: Test Packages (3.10)
- GitHub Check: Test Packages (3.11)
- GitHub Check: Build Packages (3.11)
- GitHub Check: Lint
🔇 Additional comments (11)
packages/traceloop-sdk/tests/test_conversation_id.py (2)
5-29: LGTM!The test correctly validates that conversation_id propagates to spans when set before workflow execution. The assertions verify both span order and attribute values.
32-56: LGTM!The test correctly validates conversation_id propagation when set within a workflow. This complements the first test by covering the scenario where the ID is set during workflow execution.
packages/traceloop-sdk/traceloop/sdk/__init__.py (2)
30-30: LGTM!The import is correctly placed alongside related tracing functions.
205-207: LGTM!The method follows the same delegation pattern as
set_association_properties, maintaining API consistency.packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py (2)
245-252: LGTM!The implementation correctly stores the conversation_id in both the context (for propagation to child spans) and the current span (for immediate attribution). The dual approach ensures coverage for both scenarios tested.
326-328: LGTM!The propagation logic correctly retrieves the conversation_id from context and sets it on new spans, consistent with other context-propagated attributes in the same function.
packages/sample-app/sample_app/chats/gemini_chatbot.py (5)
1-14: LGTM!The initialization correctly sources the API key from environment variables, adhering to the coding guideline that prohibits hardcoding secrets.
17-49: LGTM!The tool implementations use appropriate mock data for a sample application, making it easy to understand the chatbot's capabilities without external dependencies.
52-107: LGTM!The tool declarations are well-structured with proper schema definitions and clear descriptions for the Gemini model.
111-120: LGTM!The function execution router is straightforward and handles unknown functions gracefully.
123-186: LGTM!The workflow correctly demonstrates the use of
Traceloop.set_conversation_id()and implements a proper tool-call handling loop with conversation history management.
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 f6f8d60 in 1 minute and 0 seconds. Click for details.
- Reviewed
22lines 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/traceloop/sdk/__init__.py:29
- Draft comment:
Exposing 'associations' and 'AssociationProperty' in the top-level module is useful, but please add a brief docstring to clarify their intended use in the public API. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
2. packages/traceloop-sdk/traceloop/sdk/__init__.py:207
- Draft comment:
Assigning 'associations = associations' as a class attribute exposes the module; consider adding a comment or docstring to clarify its usage to avoid potential confusion with local variables. - Reason this comment was not posted:
Confidence changes required:33%<= threshold50%None
Workflow ID: wflow_xENdnKzeIcq6TXun
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
🧹 Nitpick comments (4)
packages/sample-app/sample_app/chats/gemini_chatbot.py (3)
136-186: Potential infinite loop if model repeatedly returns function calls.The
while Trueloop relies on the model eventually returning a text response. If the model continuously returns function calls (e.g., due to a malformed prompt or API issue), this loop will run indefinitely.Consider adding a maximum iteration limit:
+ MAX_TOOL_CALLS = 10 + tool_call_count = 0 + # Keep trying until we get a final response (handle tool calls) while True: + if tool_call_count >= MAX_TOOL_CALLS: + return "I apologize, but I'm having trouble completing this request.", conversation_history + # Generate content with tools response = client.models.generate_content( ... ) # Check if the model wants to use a tool if response.candidates[0].content.parts[0].function_call: + tool_call_count += 1 function_call = response.candidates[0].content.parts[0].function_call
148-152: Add defensive checks for response structure.Direct indexing into
response.candidates[0].content.parts[0]can raiseIndexErrororAttributeErrorif the response structure is unexpected (e.g., empty candidates or parts).- if response.candidates[0].content.parts[0].function_call: + if (response.candidates + and response.candidates[0].content + and response.candidates[0].content.parts + and response.candidates[0].content.parts[0].function_call): function_call = response.candidates[0].content.parts[0].function_call
220-222: Consider catching more specific exceptions.The static analysis tool flags catching the broad
Exceptionclass. For a sample app this is acceptable, but catching specific exceptions (e.g.,google.api_core.exceptions.GoogleAPIError) would provide better error handling.packages/traceloop-sdk/traceloop/sdk/__init__.py (1)
32-33: Add__all__to clarify public exports and silence linter.The
AssociationPropertyimport is for re-export purposes, which is valid. However, Flake8 flags it as unused (F401). Consider adding an__all__declaration to explicitly document the public API and silence the linter:__all__ = ["Traceloop", "AssociationProperty"]Alternatively, the sample app (
gemini_chatbot.py) correctly imports it, confirming the re-export is used.
📜 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/sample_app/chats/gemini_chatbot.py(1 hunks)packages/traceloop-sdk/tests/test_associations.py(1 hunks)packages/traceloop-sdk/traceloop/sdk/__init__.py(2 hunks)packages/traceloop-sdk/traceloop/sdk/tracing/associations.py(1 hunks)packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Store API keys only in environment variables/secure vaults; never hardcode secrets in code
Use Flake8 for code linting and adhere to its rules
Files:
packages/traceloop-sdk/traceloop/sdk/tracing/tracing.pypackages/traceloop-sdk/traceloop/sdk/tracing/associations.pypackages/sample-app/sample_app/chats/gemini_chatbot.pypackages/traceloop-sdk/tests/test_associations.pypackages/traceloop-sdk/traceloop/sdk/__init__.py
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: traceloop/openllmetry PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-17T15:06:48.109Z
Learning: For debugging OpenTelemetry spans, use ConsoleSpanExporter with Traceloop to print spans to console
🧬 Code graph analysis (3)
packages/sample-app/sample_app/chats/gemini_chatbot.py (4)
packages/traceloop-sdk/traceloop/sdk/__init__.py (3)
Traceloop(38-272)init(50-200)get(256-272)packages/traceloop-sdk/traceloop/sdk/tracing/associations.py (1)
AssociationProperty(7-14)packages/traceloop-sdk/traceloop/sdk/client/client.py (1)
Client(12-67)packages/traceloop-sdk/traceloop/sdk/prompts/model.py (1)
Tool(47-49)
packages/traceloop-sdk/tests/test_associations.py (3)
packages/traceloop-sdk/traceloop/sdk/__init__.py (1)
Traceloop(38-272)packages/traceloop-sdk/traceloop/sdk/tracing/associations.py (1)
AssociationProperty(7-14)packages/traceloop-sdk/traceloop/sdk/utils/in_memory_span_exporter.py (1)
get_finished_spans(40-43)
packages/traceloop-sdk/traceloop/sdk/__init__.py (1)
packages/traceloop-sdk/traceloop/sdk/tracing/associations.py (1)
AssociationProperty(7-14)
🪛 Flake8 (7.3.0)
packages/traceloop-sdk/traceloop/sdk/__init__.py
[error] 33-33: 'traceloop.sdk.tracing.associations.AssociationProperty' imported but unused
(F401)
🪛 Ruff (0.14.7)
packages/sample-app/sample_app/chats/gemini_chatbot.py
220-220: Do not catch blind exception: Exception
(BLE001)
⏰ 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). (5)
- GitHub Check: Test Packages (3.11)
- GitHub Check: Test Packages (3.12)
- GitHub Check: Build Packages (3.11)
- GitHub Check: Test Packages (3.10)
- GitHub Check: Lint
🔇 Additional comments (12)
packages/sample-app/sample_app/chats/gemini_chatbot.py (2)
1-14: LGTM on initialization and API key handling.The API key is correctly retrieved from an environment variable (
os.environ.get("GENAI_API_KEY")), which aligns with the coding guidelines for secure secret handling. Traceloop initialization is properly placed at module level.
123-128: Good use of the new associations API.The
process_messagefunction correctly uses the newTraceloop.associations.set()API to associate theconversation_idwith the current trace context.packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py (1)
316-320: LGTM on associations handling in span processor.The implementation correctly retrieves associations from context, validates it's a dictionary, and sets each key-value pair as span attributes. The
str(value)coercion ensures type safety for span attributes.Note: The associations are set as top-level attributes (e.g.,
conversation_id) whereas the existingassociation_propertiesuses a prefixed format (traceloop.association.properties.{key}). This appears intentional for cleaner attribute names, but verify this distinction is documented.packages/traceloop-sdk/traceloop/sdk/__init__.py (1)
206-207: LGTM on associations namespace exposure.The
associations = associationspattern correctly exposes the module as a class attribute, enabling the cleanTraceloop.associations.set(...)API usage demonstrated in the sample app and tests.packages/traceloop-sdk/tests/test_associations.py (5)
1-4: LGTM on imports.The imports correctly reference the new public API (
Traceloop,AssociationProperty) and existing decorators.
6-29: Good test for single association.The test properly verifies that a single association is propagated to both task and workflow spans. The assertion on span names ensures correct span ordering.
32-65: Good test for multiple associations.Comprehensive verification that all three associations are present on both span types.
68-98: Good test for associations set within workflow.This test validates an important use case where associations are set after the workflow span has started, ensuring the associations still propagate to child spans.
101-123: Test isolation is already properly handled. Theclear_exporterfixture (lines 31-37 in conftest.py) is marked asautouse=Truewith function scope, which means it automatically runs before each test. It both clears the exporter's span collection viaexporter.clear()and resets the OpenTelemetry context by callingattach(Context()). This prevents any state leakage between tests.packages/traceloop-sdk/traceloop/sdk/tracing/associations.py (3)
1-14: LGTM on enum definition.The
AssociationPropertyenum correctly inherits fromstrfor convenient string usage in span attributes. The standard properties cover common tracing use cases.
21-53: Function correctly implements dual storage pattern.The implementation properly:
- Stores associations in context for propagation to child spans via the span processor
- Sets attributes directly on the current span (if recording) for immediate association
One consideration: The function name
setshadows Python's builtinsettype within importing modules. Since it's accessed viaTraceloop.associations.set(), this is acceptable.
17-18: No action needed — Python 3.10+ is the minimum requirement and fully supports thetuple[...]syntax.The SDK requires Python 3.10 or higher, which natively supports PEP 585 syntax (
tuple[...]). Usingtyping.Tupleis unnecessary and would be a step backward.Likely an incorrect or invalid review 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 36dc637 in 1 minute and 22 seconds. Click for details.
- Reviewed
239lines of code in5files - Skipped
0files when reviewing. - Skipped posting
7draft 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/sample-app/sample_app/chats/gemini_chatbot.py:10
- Draft comment:
Good assignment of the Traceloop client to 'traceloop'. Consider adding a check to ensure that Traceloop.init() doesn't return None before using its associations. - Reason this comment was not posted:
Confidence changes required:33%<= threshold50%None
2. packages/sample-app/sample_app/chats/gemini_chatbot.py:128
- Draft comment:
Using the client instance's associations.set() is consistent with the new design. Ensure that associations are correctly propagated to the spans. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
3. packages/traceloop-sdk/tests/test_associations.py:60
- Draft comment:
Switching to client.associations.set() throughout tests aligns with the updated SDK design. The removal of THREAD_ID in tests now matches the updated AssociationProperty enum. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
4. packages/traceloop-sdk/tests/test_associations.py:121
- Draft comment:
Replacing THREAD_ID with USER_ID in associations (within workflow) is a breaking change; ensure this change is clearly documented for downstream users. - 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 a change is documented for downstream users. This falls under the rule of not asking the author to ensure behavior is intended or to update documentation. The comment does not provide a specific code suggestion or ask for a test to be written.
5. packages/traceloop-sdk/traceloop/sdk/__init__.py:37
- Draft comment:
Defining all clarifies the public API. Note that removing the associations namespace from the Traceloop class directs users to access associations via the Client instance. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
6. packages/traceloop-sdk/traceloop/sdk/client/client.py:72
- Draft comment:
Attaching the associations module to the Client instance (self.associations) is clear. Consider using a more specific type hint than ModuleType if a defined interface is available. - Reason this comment was not posted:
Confidence changes required:33%<= threshold50%None
7. packages/traceloop-sdk/traceloop/sdk/tracing/associations.py:14
- Draft comment:
Removal of the THREAD_ID property from AssociationProperty is a breaking change. Ensure that documentation and downstream integrations are updated accordingly. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =40%<= threshold50%The comment is asking the PR author to ensure documentation and downstream integrations are updated, which is similar to asking them to ensure the change is tested or verified. This violates the rule against asking the author to ensure certain actions are taken. However, it does point out a breaking change, which is useful information. The comment could be rephrased to focus on confirming the intention of the breaking change rather than ensuring updates.
Workflow ID: wflow_kXUxaHfyCIadrN1s
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: 3
🧹 Nitpick comments (5)
packages/traceloop-sdk/tests/test_associations.py (1)
48-171: Avoid relying on span ordering; select spans by name insteadAll four tests assume:
- Exactly two spans are exported in a specific order (task first, then workflow), and
- Index into
spans[0]/spans[1]based on that order.If the processor/exporter ever changes how spans are flushed, or additional spans are emitted in the same test context, these assertions can start failing for ordering reasons even when associations are correct.
To make the tests more robust, consider selecting spans by name:
- spans = exporter.get_finished_spans() - assert [span.name for span in spans] == [ - "test_single_task.task", - "test_single_association.workflow", - ] - - task_span = spans[0] - workflow_span = spans[1] + spans = exporter.get_finished_spans() + names = [span.name for span in spans] + assert "test_single_task.task" in names + assert "test_single_association.workflow" in names + + spans_by_name = {span.name: span for span in spans} + task_span = spans_by_name["test_single_task.task"] + workflow_span = spans_by_name["test_single_association.workflow"]and apply the same pattern in the other tests.
packages/traceloop-sdk/traceloop/sdk/__init__.py (1)
32-38: Optional: sort__all__to align with Ruff/style expectationsRuff flags
__all__here as unsorted (RUF022). Not a functional issue, but if you want to keep the repo’s style/linting fully green, you can reorder it, e.g.:-__all__ = ["Traceloop", "Client", "Instruments", "associations", "AssociationProperty"] +__all__ = ["AssociationProperty", "Client", "Instruments", "Traceloop", "associations"]packages/traceloop-sdk/traceloop/sdk/tracing/associations.py (1)
7-52: Align type alias and docs with the actual API (and consider avoidingsetbuiltin shadowing)A few small inconsistencies/nits in this module:
Type alias vs implementation
Associationis defined astuple[AssociationProperty, str], butset()accepts any key type and handles non‑AssociationPropertyvalues in theelsebranch.- Either:
- Widen the alias to reflect accepted keys (e.g.
Union[AssociationProperty, str]), or- Drop the
elsebranch and enforceAssociationPropertykeys only.That keeps type checkers and runtime behavior aligned.
Docstring example doesn’t match the public surface
- The example uses
Traceloop.associations.set(...), but the API exposed in this PR is:
- module-level
associationsviafrom traceloop.sdk import associations, andclient.associationsonClient.- Consider updating the example to something like:
from traceloop.sdk import associations, AssociationProperty associations.set([(AssociationProperty.CONVERSATION_ID, "conv-123")])Name
setshadows the builtin
- Within this module
setnow refers to the association helper rather than the builtin set type. It’s not currently causing issues (you don’t callset()inside), but it may be mildly confusing.- If you’re open to a rename before this becomes widely used, something like
set_associationswould avoid the shadowing.None of these are blockers, but tightening them up would make the API clearer and easier to use correctly.
packages/sample-app/sample_app/chats/gemini_chatbot.py (2)
29-33: Fix UTC/timezone inconsistency inget_current_timeThe comment says “just return current UTC time”, but the implementation uses
datetime.now(), which is local time, while the string labels it as({timezone}).To avoid confusion, either:
- Actually return UTC:
-from datetime import datetime +from datetime import datetime, timezone @@ -def get_current_time(timezone: str = "UTC") -> str: - """Get the current time in a specific timezone.""" - # Simplified - just return current UTC time - return f"Current time ({timezone}): {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" +def get_current_time(timezone: str = "UTC") -> str: + """Get the current time in a specific timezone.""" + # Simplified - just return current UTC time + utc_now = datetime.now(timezone.utc) + return f"Current time ({timezone}): {utc_now.strftime('%Y-%m-%d %H:%M:%S')} UTC"
- Or adjust the comment/label to clearly state it’s using local time.
215-223: Consider narrowing the broadexcept ExceptioninmainFor an interactive sample, catching
Exceptionand printing a friendly message is understandable, but it also hides useful details (and may mask programming errors).If you want to keep the UX but reduce risk:
- Catch expected runtime errors explicitly (e.g., API errors, misconfiguration), and
- Let unexpected exceptions surface (or at least re‑raise after logging).
For example:
from google.genai import errors as genai_errors try: assistant_message, conversation_history = process_message( chat_id, user_message, conversation_history ) except (genai_errors.APIError, RuntimeError) as e: print(f"\nError: {e}") print("Please try again.")This keeps the sample friendly while avoiding swallowing unrelated bugs.
📜 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/sample_app/chats/gemini_chatbot.py(1 hunks)packages/traceloop-sdk/tests/test_associations.py(1 hunks)packages/traceloop-sdk/traceloop/sdk/__init__.py(1 hunks)packages/traceloop-sdk/traceloop/sdk/client/client.py(3 hunks)packages/traceloop-sdk/traceloop/sdk/tracing/associations.py(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Store API keys only in environment variables/secure vaults; never hardcode secrets in code
Use Flake8 for code linting and adhere to its rules
Files:
packages/traceloop-sdk/tests/test_associations.pypackages/traceloop-sdk/traceloop/sdk/client/client.pypackages/traceloop-sdk/traceloop/sdk/tracing/associations.pypackages/sample-app/sample_app/chats/gemini_chatbot.pypackages/traceloop-sdk/traceloop/sdk/__init__.py
🧠 Learnings (1)
📓 Common learnings
Learnt from: nina-kollman
Repo: traceloop/openllmetry PR: 3219
File: packages/traceloop-sdk/tests/datasets/mock_objects.py:105-106
Timestamp: 2025-08-04T15:23:44.799Z
Learning: In the traceloop-sdk project, directly accessing private attributes like _client is acceptable in test mock objects and utilities, even though it breaks encapsulation principles, because it's isolated to test code and not production code.
🧬 Code graph analysis (2)
packages/traceloop-sdk/tests/test_associations.py (3)
packages/traceloop-sdk/traceloop/sdk/__init__.py (2)
Traceloop(40-271)init(52-202)packages/traceloop-sdk/traceloop/sdk/tracing/associations.py (1)
AssociationProperty(7-13)packages/traceloop-sdk/traceloop/sdk/utils/in_memory_span_exporter.py (4)
export(45-51)InMemorySpanExporter(22-61)clear(35-38)get_finished_spans(40-43)
packages/traceloop-sdk/traceloop/sdk/__init__.py (2)
packages/traceloop-sdk/traceloop/sdk/tracing/associations.py (1)
AssociationProperty(7-13)packages/traceloop-sdk/traceloop/sdk/client/client.py (1)
Client(15-72)
🪛 Flake8 (7.3.0)
packages/traceloop-sdk/traceloop/sdk/client/client.py
[error] 3-3: 'typing.TYPE_CHECKING' imported but unused
(F401)
🪛 Ruff (0.14.7)
packages/sample-app/sample_app/chats/gemini_chatbot.py
220-220: Do not catch blind exception: Exception
(BLE001)
packages/traceloop-sdk/traceloop/sdk/__init__.py
37-37: __all__ is not sorted
Apply an isort-style sorting to __all__
(RUF022)
⏰ 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). (5)
- GitHub Check: Build Packages (3.11)
- GitHub Check: Lint
- GitHub Check: Test Packages (3.11)
- GitHub Check: Test Packages (3.10)
- GitHub Check: Test Packages (3.12)
| else: | ||
| current_associations[str(prop)] = value |
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.
why needed
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 c0b2818 in 1 minute and 53 seconds. Click for details.
- Reviewed
171lines of code in4files - 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/traceloop/sdk/__init__.py:32
- Draft comment:
Refactored associations import and all export looks correct. Ensure that documentation and client usage are updated accordingly. - Reason this comment was not posted:
Confidence changes required:0%<= threshold50%None
2. packages/traceloop-sdk/traceloop/sdk/client/client.py:69
- Draft comment:
Instantiating Associations() here is acceptable; however, if Associations only provides static methods consider exposing it as a class-level reference to avoid redundant instantiation. - Reason this comment was not posted:
Confidence changes required:33%<= threshold50%None
Workflow ID: wflow_n0KZYDF5RloKkr0O
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
packages/traceloop-sdk/traceloop/sdk/associations/associations.py
Outdated
Show resolved
Hide resolved
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
🧹 Nitpick comments (2)
packages/traceloop-sdk/traceloop/sdk/client/client.py (1)
9-70: Associations integration onClientlooks goodThe new
associationsattribute is wired correctly and exposes a clearclient.associations.set(...)entry point. SinceAssociationsonly has static behavior today, you could also expose the class directly (self.associations = Associations) if you prefer to avoid constructing an instance, but the current approach is perfectly fine and future‑proof if you ever add instance state.packages/traceloop-sdk/traceloop/sdk/associations/associations.py (1)
7-54: Refine context key usage, dict handling, and typing for associationsThe implementation matches the desired behavior, but a few small refinements would make it more robust and self‑consistent:
Use a namespaced context key instead of raw
"associations"Using a plain string risks collisions with other code using OpenTelemetry context. Consider defining a dedicated context key:
- from typing import Sequence
- from opentelemetry import trace
- from opentelemetry.context import attach, set_value, get_value
- from typing import Sequence, Union
- from opentelemetry import trace
- from opentelemetry.context import attach, set_value, get_value, create_key
+ASSOCIATIONS_KEY = create_key("traceloop.associations")
2. **Avoid mutating the associations dict from context in place** Right now `current_associations = get_value("associations") or {}` and then updating it mutates the same dict that may already be stored in context. Copying first keeps contexts logically immutable: ```diff - # Store all associations in context - current_associations = get_value("associations") or {} + # Store all associations in context + current_associations = dict(get_value(ASSOCIATIONS_KEY) or {}) for prop, value in associations: if isinstance(prop, AssociationProperty): current_associations[prop.value] = value - attach(set_value("associations", current_associations)) + attach(set_value(ASSOCIATIONS_KEY, current_associations))
Align the
Associationtype alias with the runtime behaviorThe implementation explicitly supports non‑enum properties via
else str(prop), but the alias restricts toAssociationProperty. To keep typing and behavior in sync, either drop theelsebranch or broaden the type:-# Type alias for a single association
-Association = tuple[AssociationProperty, str]
+# Type alias for a single association
+Association = tuple[Union[AssociationProperty, str], str]If you intend to *only* support `AssociationProperty`, you can simplify by removing the `else` path in the span loop instead: ```diff - if span and span.is_recording(): - for prop, value in associations: - prop_name = prop.value if isinstance(prop, AssociationProperty) else str(prop) - span.set_attribute(prop_name, value) + if span and span.is_recording(): + for prop, value in associations: + # prop is always an AssociationProperty if you keep the stricter type alias + span.set_attribute(prop.value, value)These changes are not strictly required for correctness in the current code, but they tighten the API and reduce chances of subtle context or typing surprises as the SDK evolves.
📜 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 (3)
packages/traceloop-sdk/traceloop/sdk/__init__.py(1 hunks)packages/traceloop-sdk/traceloop/sdk/associations/associations.py(1 hunks)packages/traceloop-sdk/traceloop/sdk/client/client.py(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Store API keys only in environment variables/secure vaults; never hardcode secrets in code
Use Flake8 for code linting and adhere to its rules
Files:
packages/traceloop-sdk/traceloop/sdk/client/client.pypackages/traceloop-sdk/traceloop/sdk/associations/associations.pypackages/traceloop-sdk/traceloop/sdk/__init__.py
🧬 Code graph analysis (2)
packages/traceloop-sdk/traceloop/sdk/client/client.py (1)
packages/traceloop-sdk/traceloop/sdk/associations/associations.py (1)
Associations(20-54)
packages/traceloop-sdk/traceloop/sdk/__init__.py (2)
packages/traceloop-sdk/traceloop/sdk/associations/associations.py (2)
Associations(20-54)AssociationProperty(7-13)packages/traceloop-sdk/traceloop/sdk/client/client.py (1)
Client(13-70)
🪛 Ruff (0.14.7)
packages/traceloop-sdk/traceloop/sdk/__init__.py
36-36: __all__ is not sorted
Apply an isort-style sorting to __all__
(RUF022)
⏰ 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). (5)
- GitHub Check: Test Packages (3.11)
- GitHub Check: Test Packages (3.10)
- GitHub Check: Test Packages (3.12)
- GitHub Check: Lint
- GitHub Check: Build Packages (3.11)
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 0e8ac3e in 1 minute and 44 seconds. Click for details.
- Reviewed
44lines of code in3files - 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/sample-app/sample_app/chats/gemini_chatbot.py:7
- Draft comment:
Ensure 'traceloop.associations.set' is valid post-refactor; if 'associations' is no longer an instance property, use Traceloop.set_association_properties instead. - Reason this comment was not posted:
Comment was on unchanged code.
2. packages/traceloop-sdk/traceloop/sdk/__init__.py:29
- Draft comment:
Removing AssociationProperty from top-level exports is breaking; update docs and inform users of new import path. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =20%<= threshold50%The comment is suggesting a documentation update and informing users about a breaking change. It doesn't ask for confirmation or testing, but it does suggest an action related to documentation, which is not allowed by the rules.
3. packages/traceloop-sdk/traceloop/sdk/associations/__init__.py:1
- Draft comment:
Consider adding a module-level docstring to explain the purpose and usage of the associations re-exports. - Reason this comment was not posted:
Confidence changes required:50%<= threshold50%None
Workflow ID: wflow_bmOrcnwGmSvCaXDf
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.
Caution
Changes requested ❌
Reviewed 23d088f in 1 minute and 44 seconds. Click for details.
- Reviewed
16lines of code in1files - Skipped
0files when reviewing. - Skipped posting
0draft 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.
Workflow ID: wflow_emu8Y314x6VTuzFs
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/sample-app/sample_app/chats/gemini_chatbot.py (1)
6-14: Avoid depending onTraceloop.initreturning a client and validateGENAI_API_KEYupfront
Traceloop.init(...)returnsOptional[Client]and will returnNonewhen tracing is disabled or misconfigured (e.g., missingTRACELOOP_API_KEY). In that casetraceloop.associations.set(...)on Line 129 will raiseAttributeError, and the genericexcept Exceptioninmain()will turn every request into a vague error.Separately,
genai.Client(api_key=os.environ.get("GENAI_API_KEY"))will passNoneif the env var is missing, which leads to confusing failures later instead of a clear configuration error.You can make the sample more robust and decouple it from the optional return value of
Traceloop.initby:
- Calling
Traceloop.initfor side effects only (not storing its return), and- Using the public
associationsAPI directly, and- Validating
GENAI_API_KEYbefore constructing the Gemini client.-import os -import uuid -from datetime import datetime -import google.genai as genai -from google.genai import types -from traceloop.sdk import Traceloop -from traceloop.sdk.associations import AssociationProperty -from traceloop.sdk.decorators import workflow +import os +import uuid +from datetime import datetime +import google.genai as genai +from google.genai import types +from traceloop.sdk import Traceloop, associations +from traceloop.sdk.associations import AssociationProperty +from traceloop.sdk.decorators import workflow @@ -# Initialize Traceloop for observability -traceloop = Traceloop.init(app_name="gemini_chatbot") - -# Initialize Gemini client -client = genai.Client(api_key=os.environ.get("GENAI_API_KEY")) +# Initialize Traceloop for observability (may no-op if tracing is disabled) +Traceloop.init(app_name="gemini_chatbot") + +# Initialize Gemini client +genai_api_key = os.environ.get("GENAI_API_KEY") +if not genai_api_key: + raise RuntimeError( + "GENAI_API_KEY environment variable is required to run gemini_chatbot." + ) +client = genai.Client(api_key=genai_api_key) @@ - # Set a conversation_id to identify the conversation using the associations API - traceloop.associations.set([(AssociationProperty.CONVERSATION_ID, conversation_id)]) + # Set a conversation_id to identify the conversation using the associations API + associations.set([(AssociationProperty.CONVERSATION_ID, conversation_id)])This way, missing tracing config only disables observability, while a missing Gemini key fails fast with a clear message.
Also applies to: 124-129
🧹 Nitpick comments (3)
packages/traceloop-sdk/traceloop/sdk/associations/__init__.py (1)
1-7: Sort__all__to satisfy Ruff RUF022Ruff flags the export list as unsorted. Alphabetizing it keeps things tidy and clears the warning.
-__all__ = ["Associations", "AssociationProperty", "Association"] +__all__ = ["Association", "AssociationProperty", "Associations"]packages/sample-app/sample_app/chats/gemini_chatbot.py (2)
30-33:get_current_timeclaims UTC but uses local time and ignores thetimezoneargumentThe docstring and comment say “current time in a specific timezone” / “current UTC time”, but
datetime.now()returns local time and thetimezoneparameter is unused. For a sample, at least returning real UTC avoids misleading output:def get_current_time(timezone: str = "UTC") -> str: """Get the current time in a specific timezone.""" - # Simplified - just return current UTC time - return f"Current time ({timezone}): {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" + # Simplified - just return current UTC time + return f"Current time ({timezone}): {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')}"(If you actually want timezone-aware behavior, consider wiring the
timezoneparameter through to a real tz implementation later.)
215-223: Broadexcept Exceptionin CLI loop hides root causes (Ruff BLE001)Catching bare
Exceptionhere can mask programming errors and makes debugging harder, which Ruff flags as BLE001. For this sample app, either narrow the exception types you expect (e.g., config/runtime errors) or explicitly mark the catch as intentional:- # Process the message - try: - assistant_message, conversation_history = process_message( - chat_id, user_message, conversation_history - ) - print(f"\nAssistant: {assistant_message}") - except Exception as e: - print(f"\nError: {e}") - print("Please try again.") + # Process the message + try: + assistant_message, conversation_history = process_message( + chat_id, user_message, conversation_history + ) + print(f"\nAssistant: {assistant_message}") + except Exception as e: # noqa: BLE001 + print(f"\nError: {e}") + print("Please try again.")If you know the concrete exception types from
process_message/google.genai, prefer listing those instead ofException.
📜 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/sample-app/sample_app/chats/gemini_chatbot.py(1 hunks)packages/traceloop-sdk/traceloop/sdk/associations/__init__.py(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Store API keys only in environment variables/secure vaults; never hardcode secrets in code
Use Flake8 for code linting and adhere to its rules
Files:
packages/sample-app/sample_app/chats/gemini_chatbot.pypackages/traceloop-sdk/traceloop/sdk/associations/__init__.py
🧬 Code graph analysis (2)
packages/sample-app/sample_app/chats/gemini_chatbot.py (4)
packages/traceloop-sdk/traceloop/sdk/__init__.py (3)
Traceloop(36-267)init(48-198)get(251-267)packages/traceloop-sdk/traceloop/sdk/associations/associations.py (1)
AssociationProperty(7-13)packages/traceloop-sdk/traceloop/sdk/client/client.py (1)
Client(13-70)packages/traceloop-sdk/traceloop/sdk/prompts/model.py (1)
Tool(47-49)
packages/traceloop-sdk/traceloop/sdk/associations/__init__.py (1)
packages/traceloop-sdk/traceloop/sdk/associations/associations.py (2)
Associations(20-54)AssociationProperty(7-13)
🪛 Ruff (0.14.7)
packages/sample-app/sample_app/chats/gemini_chatbot.py
221-221: Do not catch blind exception: Exception
(BLE001)
packages/traceloop-sdk/traceloop/sdk/associations/__init__.py
7-7: __all__ is not sorted
Apply an isort-style sorting to __all__
(RUF022)
⏰ 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). (5)
- GitHub Check: Test Packages (3.12)
- GitHub Check: Lint
- GitHub Check: Test Packages (3.10)
- GitHub Check: Build Packages (3.11)
- GitHub Check: Test Packages (3.11)
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 645269c in 2 minutes and 9 seconds. Click for details.
- Reviewed
41lines 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/traceloop/sdk/__init__.py:29
- Draft comment:
Imported Associations and AssociationProperty to expose the new associations API. Ensure that any related documentation and tests are updated accordingly. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%The comment is purely informative and asks the PR author to ensure that documentation and tests are updated, which violates the rules. It doesn't provide a specific suggestion or point out a specific issue with the code.
2. packages/traceloop-sdk/traceloop/sdk/__init__.py:36
- Draft comment:
Updated all to include Associations and AssociationProperty. This explicit export is good practice for a clear public API. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%This comment is purely informative, as it praises the update without providing any actionable feedback or suggestions. It doesn't align with the rules since it doesn't offer a specific code suggestion or ask for a test to be written.
3. packages/traceloop-sdk/traceloop/sdk/associations/associations.py:42
- Draft comment:
Added explicit type annotation for 'current_associations'. Removing the isinstance check assumes all association keys are of type AssociationProperty. Ensure that all callers comply with the defined Association type alias to avoid runtime issues. - Reason this comment was not posted:
Comment looked like it was already resolved.
4. packages/traceloop-sdk/traceloop/sdk/associations/associations.py:52
- Draft comment:
Simplified span attribute setting by directly using prop.value. This assumes that all keys are AssociationProperty instances. If backward compatibility with raw strings is needed, consider retaining type checking. - Reason this comment was not posted:
Comment looked like it was already resolved.
Workflow ID: wflow_1dhUDIqgWpsnO6Ke
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
packages/traceloop-sdk/traceloop/sdk/associations/associations.py
Outdated
Show resolved
Hide resolved
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 505c403 in 2 minutes and 11 seconds. Click for details.
- Reviewed
16lines 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/traceloop/sdk/__init__.py:29
- Draft comment:
Removing the import for Associations and AssociationProperty can break backward compatibility if users relied on them. Please ensure their deprecation is documented or provide alternative access. - 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% The comment is asking the PR author to "ensure deprecation is documented" or "provide alternative access" - this is essentially asking them to verify/confirm something rather than pointing out a definite code issue. The rules state "Do NOT ask the PR author to confirm their intention, to explain, to double-check things, to ensure the behavior is intended" and "Do NOT make speculative comments, such as 'If X, then Y is an issue'". This comment is speculative because it assumes users relied on these imports without evidence, and it's asking the author to ensure/verify rather than pointing to a concrete problem. The comment doesn't show that there's definitely a problem - it's a "can break" not "will break" statement. However, removing public API exports is a legitimate backward compatibility concern in library development. If these classes were previously exported in__all__, they were part of the public API. This could be a valid architectural concern rather than just speculation. While backward compatibility is important, the comment violates the rule about asking authors to "ensure" or verify things. It's phrased as a request for the author to check/document rather than pointing out a definite issue. Without evidence that these classes are actually used by external consumers, this is speculative. The comment should either show concrete evidence of usage or not be made at all. This comment should be deleted. It asks the PR author to "ensure" documentation and "provide alternative access" which violates the rules against asking authors to verify or confirm things. The comment is speculative ("can break") without showing concrete evidence of the issue.
2. packages/traceloop-sdk/traceloop/sdk/__init__.py:31
- Draft comment:
The all list was updated by removing Associations and AssociationProperty. Confirm this change is intentional and update documentation if it introduces breaking changes. - Reason this comment was not posted:
Comment looked like it was already resolved.
Workflow ID: wflow_p6UyWaxZLNWLhAX6
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
| class AssociationProperty(str, Enum): | ||
| """Standard association properties for tracing.""" | ||
|
|
||
| CONVERSATION_ID = "conversation_id" |
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.
whats the differnece between session_id and conversation_id
will we aggregate by both, when to use each
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.
conversation is a type of session. I do need to recognize that this is a conversation because it has different characteristics then other sessions. Such us first/last messages.
The term session as a stand alone is not yet determined
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
♻️ Duplicate comments (1)
packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py (1)
352-357: Addisinstancecheck for consistency and safety.The
association_propertieshandling on line 359 includesisinstance(association_properties, dict)check, but this newassociationshandling does not. This inconsistency could lead to runtime errors if the context value isn't a dict.This was flagged in a previous review. Consider applying a consistent pattern:
🔎 Suggested fix
# Handle associations associations = get_value("associations") - if associations is not None: + if associations is not None and isinstance(associations, dict): for key, value in associations.items(): span.set_attribute(key, str(value))
🧹 Nitpick comments (1)
packages/traceloop-sdk/traceloop/sdk/associations/associations.py (1)
41-46: Add defensive type check forget_value("associations")return value.The
get_value()function can return any type stored in context. If another part of the codebase accidentally sets"associations"to a non-dict value, this would cause a runtime error on line 44 when calling.items()implicitly through the loop or when merging.🔎 Suggested fix
# Store all associations in context - current_associations: dict[str, str] = get_value("associations") or {} + existing = get_value("associations") + current_associations: dict[str, str] = existing if isinstance(existing, dict) else {} for prop, value in associations: current_associations[prop.value] = value
📜 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.
📒 Files selected for processing (4)
packages/traceloop-sdk/traceloop/sdk/__init__.py(2 hunks)packages/traceloop-sdk/traceloop/sdk/associations/associations.py(1 hunks)packages/traceloop-sdk/traceloop/sdk/client/client.py(3 hunks)packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/traceloop-sdk/traceloop/sdk/client/client.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Store API keys only in environment variables/secure vaults; never hardcode secrets in code
Use Flake8 for code linting and adhere to its rules
Files:
packages/traceloop-sdk/traceloop/sdk/__init__.pypackages/traceloop-sdk/traceloop/sdk/tracing/tracing.pypackages/traceloop-sdk/traceloop/sdk/associations/associations.py
🧠 Learnings (1)
📚 Learning: 2025-08-04T15:23:44.799Z
Learnt from: nina-kollman
Repo: traceloop/openllmetry PR: 3219
File: packages/traceloop-sdk/tests/datasets/mock_objects.py:105-106
Timestamp: 2025-08-04T15:23:44.799Z
Learning: In the traceloop-sdk project, directly accessing private attributes like _client is acceptable in test mock objects and utilities, even though it breaks encapsulation principles, because it's isolated to test code and not production code.
Applied to files:
packages/traceloop-sdk/traceloop/sdk/__init__.py
⏰ 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). (5)
- GitHub Check: Test Packages (3.12)
- GitHub Check: Test Packages (3.10)
- GitHub Check: Lint
- GitHub Check: Build Packages (3.11)
- GitHub Check: Test Packages (3.11)
🔇 Additional comments (2)
packages/traceloop-sdk/traceloop/sdk/associations/associations.py (2)
1-17: LGTM on the enum and type alias definitions.The
AssociationPropertyenum inherits from bothstrandEnum, which is a good pattern for ensuring the enum values can be used directly as strings. The type alias clearly expresses the association structure.
48-52: LGTM on span attribute handling.The span attribute setting correctly guards against null/non-recording spans. Note that these attributes are set as top-level keys (e.g.,
conversation_id) unlikeassociation_propertieswhich uses a namespaced prefix. This appears intentional to differentiate the two mechanisms.
| from traceloop.sdk.client.client import Client | ||
|
|
||
|
|
||
|
|
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
🏁 Script executed:
#!/bin/bash
# Check if Associations is properly imported and exported in __init__.py
echo "=== Checking imports ==="
rg -n "from.*associations.*import|import.*Associations" packages/traceloop-sdk/traceloop/sdk/__init__.py
echo -e "\n=== Checking __all__ definition ==="
rg -n "__all__" packages/traceloop-sdk/traceloop/sdk/__init__.py
echo -e "\n=== Full file content to verify ==="
cat packages/traceloop-sdk/traceloop/sdk/__init__.pyRepository: traceloop/openllmetry
Length of output: 10780
🏁 Script executed:
#!/bin/bash
# Search for Associations and AssociationProperty class definitions
echo "=== Searching for Associations class ==="
rg -n "class Associations" --type py
echo -e "\n=== Searching for AssociationProperty class ==="
rg -n "class AssociationProperty" --type py
echo -e "\n=== Searching for any references to Associations in codebase ==="
rg -n "Associations" packages/traceloop-sdk/traceloop/sdk/ --type py | head -20Repository: traceloop/openllmetry
Length of output: 1024
🏁 Script executed:
cat packages/traceloop-sdk/traceloop/sdk/associations/__init__.pyRepository: traceloop/openllmetry
Length of output: 246
Add Associations and AssociationProperty to SDK exports.
The Associations and AssociationProperty classes are defined in the associations submodule but are not imported or exported from the main SDK __init__.py. Add these imports and create an __all__ list to expose them on the SDK surface:
from traceloop.sdk.associations import Associations, AssociationPropertyEnsure they are included in __all__ for public API consistency.
🤖 Prompt for AI Agents
In packages/traceloop-sdk/traceloop/sdk/__init__.py around line 36, the
Associations and AssociationProperty classes from traceloop.sdk.associations are
not exported; add imports for them (from traceloop.sdk.associations import
Associations, AssociationProperty) and update or create the __all__ list to
include 'Associations' and 'AssociationProperty' so they are part of the public
SDK surface.
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 1fa4840 in 8 minutes and 29 seconds. Click for details.
- Reviewed
8179lines of code in101files - Skipped
0files when reviewing. - Skipped posting
15draft 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/traceloop/sdk/client/client.py:69
- Draft comment:
Guardrails integration: Instantiating Guardrails with self._async_http is appropriate. Consider if a singleton or shared instance should be used if the client is long‐lived. - 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.
2. packages/traceloop-sdk/traceloop/sdk/client/http.py:35
- Draft comment:
Improved error formatting: The _format_error_message function consolidates error detail extraction from response JSON or text which aids in debugging. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%This comment is purely informative, as it only praises the improvement in error formatting without providing any actionable feedback or suggestions. It doesn't align with the rules for useful comments.
3. packages/traceloop-sdk/traceloop/sdk/evaluator/evaluator.py:31
- Draft comment:
Evaluator config: Passing evaluator_config to _build_evaluator_request is handled correctly to add flexibility in evaluator execution. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%This comment is purely informative and does not provide any actionable feedback or suggestions for improvement. It simply states that something is handled correctly, which does not align with the rules for useful comments.
4. packages/traceloop-sdk/traceloop/sdk/guardrails/guardrails.py:17
- Draft comment:
Guardrail decorator: The dual (async and sync) wrappers are well implemented to support both function types. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%This comment is purely informative and does not provide any actionable feedback or suggestions for improvement. It simply praises the implementation without offering any specific guidance or questions.
5. packages/traceloop-sdk/traceloop/sdk/tracing/tracing.py:312
- Draft comment:
Endpoint scheme matching: The use of match-case to select HTTP vs gRPC exporters based on the URL scheme is clear. Verify edge cases for endpoints without an explicit scheme. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%The comment is asking the PR author to verify edge cases, which falls under the category of asking them to ensure behavior is intended or tested. This violates the rules provided.
6. packages/traceloop-sdk/traceloop/sdk/evaluator/field_mapping.py:13
- Draft comment:
Synonym groups: Consider using immutable sets (e.g. frozenset) for SYNONYM_GROUPS to prevent accidental modifications. - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 30% vs. threshold = 50% This is a code quality suggestion about using immutable data structures. While technically correct that frozenset would prevent accidental modifications, I need to consider: 1) Is this clearly actionable? Yes, it's a simple change. 2) Is this important enough? It's a minor improvement. 3) Does it follow the rules? The rules say "Comments that suggest code quality refactors are good! But only if they are actionable and clear." This is actionable and clear. However, the rules also say "Do NOT comment unless there is clearly a code change required" and "Do NOT make comments that are obvious or unimportant." This feels like a minor, somewhat obvious suggestion that doesn't clearly require a change - the code works fine as-is. This is a valid code quality suggestion that is actionable and clear. The change would make the code more robust by preventing accidental mutations. It's not speculative - using immutable types for constants is a well-established Python best practice. The suggestion is specific and easy to implement. While the suggestion is technically valid, it's a minor improvement that doesn't address any actual bug or clear issue. The code works correctly as written, and there's no evidence that accidental modification is a real concern here. The rules emphasize not making comments unless there is "clearly a code change required" and to avoid "obvious or unimportant" comments. This falls into the category of a nice-to-have improvement rather than a necessary change. This is a minor code quality suggestion that, while technically correct, doesn't meet the threshold of "clearly a code change required." It's more of a stylistic preference than a necessary fix. Given the rules emphasize avoiding unimportant comments and only commenting when changes are clearly required, this should be removed.
7. packages/traceloop-sdk/traceloop/sdk/experiment/experiment.py:440
- Draft comment:
JSONL parsing: Skipping the header line is acceptable if dataset files always include a header; ensure dataset formats are consistent. - 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.
8. packages/traceloop-sdk/traceloop/sdk/experiment/utils.py:158
- Draft comment:
Trajectory extraction: Double JSON encoding of trajectory_prompts/completions may be redundant. Confirm that the final output format meets evaluator expectations. - 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 says "may be redundant" and asks to "Confirm that the final output format meets evaluator expectations." This is asking the PR author to verify/confirm something rather than pointing out a definite bug. However, there IS a real issue here: when the dicts are empty, lines 146/148 convert them to JSON strings, then line 158 encodes them again, resulting in double encoding. When non-empty, they're only encoded once. This inconsistency is a bug. But the comment is phrased as "may be redundant" and "Confirm that..." which violates the rule about not asking authors to confirm/verify. The comment should either clearly state the bug or not be made at all. The comment does identify a real code issue (inconsistent encoding behavior between empty and non-empty cases), even if it's phrased poorly. Maybe the phrasing as a question is just being cautious, and the underlying issue is valid enough to warrant keeping it. While there is a technical issue, the comment explicitly asks to "Confirm that..." which violates the rules. The comment should be actionable and definitive, not asking for confirmation. If the tool was confident about the issue, it should have stated it clearly with a suggested fix. The comment asks the author to "Confirm" something rather than stating a clear, actionable issue. This violates the rule against asking authors to verify or confirm. Even though there may be a real encoding inconsistency, the comment as written is not actionable enough and should be deleted.
9. CHANGELOG.md:18
- Draft comment:
Typo: In "support Older Version Ollama", the phrase "Older Version" seems oddly capitalized. Consider using lowercase ("older version") for consistency. - 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% This is a style/formatting comment about capitalization in a changelog entry. While the capitalization does look inconsistent (other entries don't capitalize like this), changelog entries are typically auto-generated from commit messages or PR titles. The comment is very minor - it's about capitalization in documentation, not code. According to the rules, I should not comment on things that are obvious or unimportant. This is a very minor style issue in a changelog that likely won't affect anyone's understanding. The rules also say "Do NOT comment unless there is clearly a code change required" - this is documentation, not code. Additionally, changelogs are often auto-generated and may reflect the original PR title capitalization. Could this be an auto-generated changelog entry that reflects the original PR title? If so, changing it might break the automation or be inconsistent with the process. Also, is capitalization consistency in changelog entries really important enough to warrant a comment? Even if this is auto-generated, the comment is about a very minor style issue in documentation (not code). The rules explicitly state not to make comments that are obvious or unimportant. A capitalization inconsistency in a changelog entry is not important enough to warrant a code review comment, especially since it doesn't affect functionality or understanding. This comment should be deleted. It's a minor style issue in a changelog entry (documentation, not code) that doesn't warrant a review comment. The capitalization doesn't affect functionality or understanding, and changelog entries are often auto-generated from PR titles.
10. CHANGELOG.md:25
- Draft comment:
Typo: The phrase "Add agent evaluators to made by traceloop" appears to have an extra or misplaced word. Consider revising it for clarity, e.g., "Add agent evaluators made by traceloop." - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 30% vs. threshold = 50% This is a comment about a CHANGELOG file. The rules state I should not comment on things that are "obvious or unimportant." A typo in a CHANGELOG could be considered minor, but it does affect readability and professionalism. However, the rules also say "Do NOT comment unless there is clearly a code change required" and "Do NOT make purely informative comments." A CHANGELOG is documentation, not code. The comment is essentially asking for a documentation fix. The rules also say "Do NOT ask the PR author to update the PR description" which suggests documentation changes might not be priority. However, this is about the CHANGELOG content itself, not the PR description. The comment does suggest a specific change (a suggestion block), so it's actionable. But is fixing a minor grammar issue in a CHANGELOG entry important enough to warrant a comment? The rules emphasize not making obvious or unimportant comments. This seems like a minor documentation issue that doesn't affect functionality. While the grammar issue is real, CHANGELOG entries are typically generated automatically from commit messages or PR titles, and minor grammar issues in them are often not critical. The comment might be considered too minor or "obvious" - anyone reading it can understand the intent. Also, fixing CHANGELOG grammar might not be a priority compared to actual code issues. However, the CHANGELOG is user-facing documentation that will be read by many people, and maintaining professional, clear language is important. The suggested fix is simple and improves clarity. This is not just a nitpick but a genuine improvement to readability. The comment is actionable with a clear suggestion. This is a borderline case. While the grammar issue is real and the fix would improve the CHANGELOG, it's a minor documentation issue in an automatically-generated file. Given the rules emphasize not making "obvious or unimportant" comments and that this doesn't affect code functionality, I lean toward deleting this comment as it's too minor.
11. packages/opentelemetry-instrumentation-google-generativeai/pyproject.toml:14
- Draft comment:
There appears to be a typographical error in the repository URL. The URL uses "openllmetry" while the package name and description use "opentelemetry". Please verify whether the URL should be corrected to "opentelemetry". - Reason this comment was not posted:
Comment was on unchanged code.
12. packages/opentelemetry-instrumentation-mcp/pyproject.toml:14
- Draft comment:
Typographical error: The repository URL contains 'openllmetry', which appears to be a misspelling. It should be 'opentelemetry' to match the project name. - Reason this comment was not posted:
Comment was on unchanged code.
13. packages/opentelemetry-instrumentation-mistralai/pyproject.toml:14
- Draft comment:
There's a potential typo in the repository URL on line 14: "openllmetry" is used. It might be intended to be "opentelemetry". - Reason this comment was not posted:
Comment was on unchanged code.
14. packages/opentelemetry-instrumentation-replicate/pyproject.toml:14
- Draft comment:
Typographical error: The repository URL contains "openllmetry". It may be a typo for "opentelemetry". - Reason this comment was not posted:
Comment was on unchanged code.
15. packages/sample-app/sample_app/experiment/made_by_traceloop/travel_agent_exp.py:59
- Draft comment:
Typo in the comment: Instead of "This is the agents input", consider using "This is the agent's input" for clarity. - 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% This is a purely stylistic/grammatical comment about an inline code comment. While it's technically correct that there's a typo, the rules state "Do NOT comment unless there is clearly a code change required" and "Do NOT make comments that are obvious or unimportant." A typo in a code comment doesn't require a code change - the code functions identically. This is an unimportant, purely cosmetic issue. The rules emphasize only commenting when there's a clear code change required, and fixing grammar in comments doesn't meet that bar. Could this be considered a code quality improvement? Some teams do care about proper grammar in comments for professionalism. However, the rules explicitly say not to make obvious or unimportant comments, and a missing apostrophe in a comment is quite minor. While some teams value proper grammar, the rules are clear that comments should only be made when there's a clear code change required. A grammatical error in a comment doesn't affect functionality, and this falls under "obvious or unimportant" - it's a trivial typo that doesn't impact understanding. This comment should be deleted. It's pointing out a minor grammatical error in a code comment that doesn't affect functionality or understanding. This violates the rule against making obvious or unimportant comments.
Workflow ID: wflow_6N3aRSuUsfwKPqha
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.
Important
Looks good to me! 👍
Reviewed 6b49b51 in 26 seconds. Click for details.
- Reviewed
408lines of code in2files - 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/tests/test_association_properties.py:1
- Draft comment:
All tests in this file were removed. Ensure that association propagation is still properly tested or that new tests are added. - 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.
2. packages/traceloop-sdk/tests/test_associations.py:1
- Draft comment:
This file’s tests covering association creation and propagation have been removed. Confirm that the new implementation is adequately covered by alternative tests. - 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_9NKWwK5xTIAsXQaQ
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: 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.
📒 Files selected for processing (2)
packages/traceloop-sdk/tests/test_association_properties.py(0 hunks)packages/traceloop-sdk/traceloop/sdk/associations/associations.py(1 hunks)
💤 Files with no reviewable changes (1)
- packages/traceloop-sdk/tests/test_association_properties.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Store API keys only in environment variables/secure vaults; never hardcode secrets in code
Use Flake8 for code linting and adhere to its rules
Files:
packages/traceloop-sdk/traceloop/sdk/associations/associations.py
🧬 Code graph analysis (1)
packages/traceloop-sdk/traceloop/sdk/associations/associations.py (1)
packages/traceloop-sdk/traceloop/sdk/datasets/attachment.py (1)
attach(200-227)
⏰ 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). (5)
- GitHub Check: Test Packages (3.12)
- GitHub Check: Test Packages (3.11)
- GitHub Check: Test Packages (3.10)
- GitHub Check: Build Packages (3.11)
- GitHub Check: Lint
🔇 Additional comments (4)
packages/traceloop-sdk/traceloop/sdk/associations/associations.py (4)
1-6: LGTM: Imports and constant definition.The imports are appropriate, and defining
ASSOCIATIONS_KEYas a constant addresses the previous review feedback about avoiding hardcoded strings.
8-14: LGTM: Well-defined enum.The
AssociationPropertyenum is properly structured with clear, standard association properties suitable for tracing contexts.
17-18: LGTM: Clear type alias.The
Associationtype alias provides good type safety and readability.
49-53: LGTM: Proper span attribute handling.The code correctly checks for span existence and recording status before setting attributes, following OpenTelemetry best practices.
packages/traceloop-sdk/traceloop/sdk/associations/associations.py
Outdated
Show resolved
Hide resolved
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 a924f40 in 29 seconds. Click for details.
- Reviewed
21lines 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/traceloop/sdk/associations/associations.py:48
- Draft comment:
Good improvement: replacing the hard-coded string with the ASSOCIATIONS_KEY constant boosts consistency and maintainability. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =0%<= threshold50%This comment is purely informative, as it only states the benefit of a change without suggesting any action or pointing out a potential issue. It doesn't align with the rules for useful comments in a pull request review.
Workflow ID: wflow_Kk8PofeqazAD0V5U
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
🧹 Nitpick comments (2)
packages/traceloop-sdk/traceloop/sdk/associations/associations.py (2)
44-46: Add defensive type checking for context value.The
get_value(ASSOCIATIONS_KEY)call assumes it returns eitherNoneor a dict. If theASSOCIATIONS_KEYis accidentally reused elsewhere in the codebase with a different type, line 46 will raise aTypeError.🔎 Proposed defensive check
- current_associations: dict[str, str] = get_value(ASSOCIATIONS_KEY) or {} + existing = get_value(ASSOCIATIONS_KEY) + current_associations: dict[str, str] = existing if isinstance(existing, dict) else {}
26-42: Consider validating association values.The method accepts any string value, including empty strings. Depending on your requirements, you may want to validate that values are non-empty to prevent inadvertent errors in downstream processing.
🔎 Example validation
@staticmethod def set(associations: Sequence[Association]) -> None: """...""" # Validate before processing for prop, value in associations: if not value or not value.strip(): raise ValueError(f"Association value for {prop.value} cannot be empty") # Existing logic... current_associations: dict[str, str] = get_value(ASSOCIATIONS_KEY) or {} # ...
📜 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.
📒 Files selected for processing (1)
packages/traceloop-sdk/traceloop/sdk/associations/associations.py(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Store API keys only in environment variables/secure vaults; never hardcode secrets in code
Use Flake8 for code linting and adhere to its rules
Files:
packages/traceloop-sdk/traceloop/sdk/associations/associations.py
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: traceloop/openllmetry PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-08-17T15:06:48.109Z
Learning: For debugging OpenTelemetry spans, use ConsoleSpanExporter with Traceloop to print spans to console
⏰ 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). (5)
- GitHub Check: Test Packages (3.11)
- GitHub Check: Lint
- GitHub Check: Test Packages (3.12)
- GitHub Check: Build Packages (3.11)
- GitHub Check: Test Packages (3.10)
🔇 Additional comments (3)
packages/traceloop-sdk/traceloop/sdk/associations/associations.py (3)
1-8: LGTM! Imports and constant definition are clean.The past review comment about using the
ASSOCIATIONS_KEYconstant has been properly addressed—line 48 correctly uses the constant instead of a hardcoded string.
9-15: LGTM! Clear and well-defined enum.The standard association properties are appropriately scoped. The distinction between
SESSION_IDandCONVERSATION_IDhas been clarified in past reviews.
18-19: LGTM! Clean type alias.The
Associationtype alias improves readability and properly constrains the association structure.
feat(instrumentation): ...orfix(instrumentation): ....Important
Introduces
AssociationPropertyfor tracing, a chatbot with integrated tools, and enhances the Traceloop SDK for improved observability and interaction.AssociationPropertyinassociations.pyfor tracing properties likeCONVERSATION_ID,CUSTOMER_ID,USER_ID, andSESSION_ID.gemini_chatbot.pywith tools for weather, time, and knowledge base queries.process_message()ingemini_chatbot.pyto handle messages with tool support and chat ID association.Associationsintoclient.pyandtracing.pyfor managing trace associations.default_span_processor_on_start()intracing.pyto handle new associations.test_association_properties.pyas part of refactoring.This description was created by
for a924f40. You can customize this summary. It will automatically update as commits are pushed.
Summary by CodeRabbit
New Features
Tests
✏️ Tip: You can customize this high-level summary in your review settings.