Skip to content

feat: implement tool calling support for workflow API #21

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

Merged
merged 21 commits into from
Aug 10, 2025
Merged

Conversation

nirga
Copy link
Member

@nirga nirga commented Aug 9, 2025

Important

Implement tool calling support in workflow API with enhanced logging and a sample app.

  • New Features:
    • Implement tool calling support in traceloop-sdk with LogPrompt and LogCompletion functions.
    • Add Tool, ToolFunction, and ToolCall types in tracing_types.go.
    • Add sample application in sample-app demonstrating tool calling and prompt logging.
  • Improvements:
    • Enhance logging with detailed tool call metadata in sdk.go.
    • Update ci.yml to test against Go versions 1.22, 1.23, and 1.24.
    • Improve URL handling in utils.go and tracing.go for base URLs.
  • Tests:
    • Add tests in sdk_test.go for span attributes including tool call details.
  • Dependencies:
    • Upgrade dependencies in go.mod files to support newer Go and OpenTelemetry versions.

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


Summary by CodeRabbit

  • New Features

    • Added a sample application demonstrating prompt logging and tool calling with enhanced documentation and usage instructions.
    • Introduced support for logging detailed tool calls and tool metadata in traces, including tool definitions and invocation details.
    • Expanded data models to represent tools and tool calls within prompts and messages.
  • Improvements

    • Enhanced logging to include richer metadata, such as workflow association properties and JSON-serialized messages.
    • Improved environment variable handling and command-line branching in the sample app.
    • Upgraded dependencies, including support for newer Go and OpenTelemetry versions.
  • Bug Fixes

    • Improved URL handling for base URLs in HTTP requests and tracing exporters to ensure compatibility and correctness.
  • Tests

    • Added comprehensive tests to verify span attributes for prompt and completion logging, including tool call details.
  • Chores

    • Updated CI workflow to test against newer Go versions and improved build environment settings.
    • Added and updated .gitignore files to better manage sensitive and mock data.

nirga and others added 8 commits August 8, 2025 15:14
- Fix tool call attribute naming to match Python OpenLLMetry
- Use llm.completions.X.tool_calls.Y.name instead of function.name
- Use llm.completions.X.tool_calls.Y.arguments instead of function.arguments
- Remove incorrect 'type' attribute from tool calls
- Fix double https:// issue in OTLP exporter URL construction
- Add comprehensive test suite for span attribute validation
- Add working tool calling sample applications
- Fix OpenAI tool definition to include required Type field
- Implement proper span duration using actual API call timing

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
…ng sample

- Fixed BaseURL in main.go to use proper HTTPS protocol
- Removed hardcoded API key from tool_calling.go, now uses environment variables
- Deleted duplicate tool-calling-sample directory (functionality exists in sample-app)
- Removed binary files from repository

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
The tool calling functionality is already implemented in sample-app/tool_calling.go,
so the duplicate directory is not needed.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
1. Add omitempty to Tool struct Function field for optional serialization
2. Add toolCall.Type attribute propagation in span attributes
3. Add error logging for JSON marshaling failures in setToolsAttribute
4. Improve temperature unit validation in tool calling sample

These changes improve error handling, completeness of tracing attributes,
and robustness of the tool calling implementation.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
HTTP Mocking Features:
- Manual HTTP mocking using httptest (no API keys needed)
- VCR recording with pre-sanitized mock cassette
- Integration test support with environment variable gating
- Comprehensive testing documentation

Security Features:
- Authorization headers automatically sanitized from recordings
- Pre-sanitized mock cassette included for CI
- Gitignore configured to prevent accidental key commits
- Request body sanitization for extra safety

CodeRabbit Review Fixes:
- Add omitempty to Tool struct Function field for optional serialization
- Add toolCall.Type propagation in both span attribute functions
- Add error logging for JSON marshaling failures in setToolsAttribute
- Improve temperature unit validation with proper error handling

All tests pass without requiring API keys, making CI/CD pipeline friendly.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Remove manual HTTP mocking approach - VCR is more realistic
- Keep only VCR recording with pre-sanitized cassette
- Update documentation to focus on single testing approach
- All tests pass without requiring API keys in CI

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
The go.opentelemetry.io/otel/exporters/stdout/stdouttrace dependency
was not used in any Go files and has been removed to clean up the
dependency tree.

All tests continue to pass after this cleanup.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
The root go.mod had incorrect require syntax with missing version
numbers and improper quotes, causing CI test failures. Fixed with:
- Proper version numbers for local modules
- Added replace directives for local development
- Removed quotes from module names

CI tests now run successfully for both sample-app and traceloop-sdk.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

coderabbitai bot commented Aug 9, 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.

Warning

Rate limit exceeded

@nirga has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 1 minutes and 1 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 0276b21 and 7952b5a.

⛔ Files ignored due to path filters (2)
  • go.work.sum is excluded by !**/*.sum
  • semconv-ai/go.sum is excluded by !**/*.sum
📒 Files selected for processing (6)
  • go.mod (1 hunks)
  • sample-app/README.md (1 hunks)
  • sample-app/main.go (2 hunks)
  • semconv-ai/go.mod (1 hunks)
  • traceloop-sdk/sdk.go (4 hunks)
  • traceloop-sdk/utils.go (1 hunks)

Walkthrough

This update introduces tool calling support and richer metadata logging to the Traceloop Go OpenLLMetry SDK and its sample applications. The SDK's data model, span attribute handling, and logging methods are extended to capture tool definitions and tool call details. The sample app demonstrates tool calling with OpenAI and includes new documentation, dependency updates, and environment handling improvements.

Changes

Cohort / File(s) Change Summary
Sample App Additions & Refactor
sample-app/README.md, sample-app/.gitignore, sample-app/main.go, sample-app/tool_calling.go, sample-app/go.mod, sample-app/workflow_example.go
Adds a README and .gitignore for sample app; refactors entry point to support workflow and tool calling examples; introduces tool calling demo; updates dependencies and environment loading; renames workflow example function.
SDK Data Model & Logging Enhancements
traceloop-sdk/tracing_types.go, traceloop-sdk/sdk.go
Extends data model with tool, tool call, and tool function structs; updates message and prompt structs; enhances span attribute logging to include tool and tool call details, JSON serialization, and workflow association properties.
SDK Dependency & Utility Updates
traceloop-sdk/go.mod, traceloop-sdk/tracing.go, traceloop-sdk/utils.go
Upgrades Go version and dependencies (notably OpenTelemetry); adjusts OTLP exporter endpoint handling; improves URL construction logic to support explicit schemes.
SDK Testing
traceloop-sdk/sdk_test.go
Adds a comprehensive test verifying span attributes and metadata for prompt and completion logging with tool calling.
CI Workflow Update
.github/workflows/ci.yml
Updates Go versions in CI, disables Go workspace and caching, and adjusts trigger events.
Module Root
go.mod
Adds a root go.mod with replace directives for local development.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SampleApp
    participant TraceloopSDK
    participant OpenAI

    User->>SampleApp: Run with "tool-calling" argument
    SampleApp->>TraceloopSDK: Initialize client
    SampleApp->>OpenAI: Send chat prompt with tool(s)
    OpenAI-->>SampleApp: Respond with tool call(s)
    SampleApp->>SampleApp: Execute local tool(s)
    SampleApp->>TraceloopSDK: Log prompt (with tool/tool call metadata)
    SampleApp->>TraceloopSDK: Log completion (with tool call results)
    SampleApp-->>User: Output results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

In fields of code, a rabbit hops,
With tools and prompts, it never stops!
Now logs are rich, with tools in tow,
And sample apps put on a show.
The SDK grows, the tests are keen—
The burrow’s brighter, swift, and clean!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch tool-calling

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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 929e4e9 in 2 minutes and 0 seconds. Click for details.
  • Reviewed 1442 lines of code in 17 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. go.mod:3
  • Draft comment:
    The root go.mod specifies Go version 1.21 while sample-app/go.mod uses 1.23.0. Align the Go version across modules for consistency.
  • Reason this comment was not posted:
    Confidence changes required: 50% <= threshold 50% None
2. traceloop-sdk/utils.go:22
  • Draft comment:
    When constructing the request URL in fetchPath, ensure that BaseURL does not end with a trailing slash to avoid a double slash in the final URL.
  • Reason this comment was not posted:
    Confidence changes required: 50% <= threshold 50% None
3. sample-app/README.md:3
  • Draft comment:
    It appears that "OpenLLMetry" may be a typographical error. Did you mean "OpenTelemetry"? Please double-check 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% The name "OpenLLMetry" appears to be a deliberate portmanteau combining "LLM" and "Telemetry". The context is about LLM tooling (OpenAI, tool calling, prompt logging). The comment assumes it's a typo but it's likely an intentional branding choice. Making assumptions about product names without being certain is risky. I could be wrong about this being intentional - maybe it really is a typo. The standard OpenTelemetry project is very well-known. Even if there's a small chance it's a typo, we shouldn't make assumptions about product names without strong evidence. The context strongly suggests this is LLM-related tooling. Delete this comment as it's making assumptions about what might be an intentional product name without strong evidence that it's actually incorrect.
4. traceloop-sdk/go.sum:66
  • Draft comment:
    I noticed that the module name "github.com/traceloop/go-openllmetry/semconv-ai" might contain a typographical error. Should it be "go-opentelemetry" (with a single 'l') instead of "go-openllmetry"?
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 0% vs. threshold = 50% This appears to be an intentional module name from the traceloop organization. The "ll" in "openllmetry" likely stands for something specific (perhaps "large language" given the "ai" in the path). This isn't a typo - it's a deliberate naming choice. Making assumptions about package names being typos without understanding the context is dangerous. I could be wrong about the meaning of "ll" in the name. Maybe it really is a typo that should be fixed. Given this is from the organization's own repository and follows their naming pattern, it's extremely unlikely to be a typo. If it were a typo, it would likely have been caught during the initial module creation. The comment should be deleted as it incorrectly assumes a deliberate module name is a typo.
5. traceloop-sdk/sdk_test.go:11
  • Draft comment:
    Typo alert: The import path 'github.com/traceloop/go-openllmetry/traceloop-sdk/config' contains 'openllmetry'. If this is intended to reference OpenTelemetry, it might be meant to be spelled 'opentelemetry'. Please double-check.
  • 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 appears to be an intentional naming choice, not a typo. The package seems to be specifically about LLMs (hence 'openllmetry' combining 'open' and 'llm'), and is building on top of OpenTelemetry for LLM-specific telemetry. The import paths for actual OpenTelemetry packages are correct (go.opentelemetry.io/otel). This is likely a deliberate name for a new project. I could be wrong about the intention - maybe it really is a typo that should be fixed. The similarity to 'opentelemetry' is very close. The consistent use of 'llm' throughout the code and the fact that this is clearly an LLM-focused package strongly suggests this is an intentional name combining 'open' and 'llm'. The comment should be deleted as it's pointing out what appears to be an intentional package naming choice, not a typo that needs fixing.

Workflow ID: wflow_A07pj55cUS3xgYJW

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

Copy link

@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: 8

🔭 Outside diff range comments (2)
traceloop-sdk/utils.go (1)

22-26: Ensure BaseURL Is Valid and Safely Construct URLs

String-concatenation with fmt.Sprintf("%s/%s", BaseURL, path) can produce double-slashes and, if the user omits a scheme, end up with an invalid request (a schemeless URL will pass through http.NewRequest but fail at send time). We should:

  • Parse and normalize instance.config.BaseURL, enforcing a default scheme if missing.
  • Use the net/url APIs (ResolveReference or JoinPath) to append the resource path cleanly.
  • Return a wrapped error on invalid BaseURL or request creation.

Apply to traceloop-sdk/utils.go:

--- a/traceloop-sdk/utils.go
+++ b/traceloop-sdk/utils.go
@@ -1,3 +1,5 @@
 package traceloop

+import (
+    "net/url"
 )
 import (
     "fmt"
@@ -19,7 +21,22 @@ func (instance *Traceloop) newGetRequest(path string) (*http.Request, error) {
-   req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/%s", instance.config.BaseURL, path), nil)
-   if err != nil {
-       fmt.Printf("Failed to create request: %v\n", err)
-       return nil, err
-   }
+   // Parse and normalize BaseURL
+   base, err := url.Parse(instance.config.BaseURL)
+   if err != nil {
+       return nil, fmt.Errorf("invalid BaseURL %q: %w", instance.config.BaseURL, err)
+   }
+   if base.Scheme == "" {
+       base.Scheme = "https"
+   }
+   // Build full URL safely
+   // Option A: using ResolveReference
+   full := base.ResolveReference(&url.URL{Path: path})
+   // Option B (Go 1.19+): fullPath, _ := url.JoinPath(base.String(), path)
+
+   req, err := http.NewRequest(http.MethodGet, full.String(), nil)
+   if err != nil {
+       return nil, fmt.Errorf("failed to create GET request for %s: %w", full.String(), err)
+   }
+   return req, nil

Don’t forget to add:

import (
    "net/url"
)

and update any callers of this helper if necessary.

sample-app/main.go (1)

49-49: Guard against empty choices to avoid panic

Directly indexing resp.Choices[0] can panic on empty results or filtered responses.

Example:

if len(resp.Choices) == 0 {
    fmt.Println("No choices returned")
    return
}
fmt.Println(resp.Choices[0].Message.Content)
🧹 Nitpick comments (10)
go.mod (1)

6-12: Local replaces: fine for dev, but gate for release; consider go.work

Using local replace directives with placeholder pseudo-versions is OK for iterative dev. Before releasing/publishing, drop these replaces or move to a workspace (go.work) to avoid accidental coupling and to enable consumers to resolve proper versions.

Action:

  • Verify CI/builds don’t rely on these replaces unintentionally.
  • Consider adopting a top-level go.work to manage the multi-module layout cleanly across the repo and sample app.
traceloop-sdk/go.mod (1)

10-10: Local development flow for semconv-ai

This module requires github.com/traceloop/go-openllmetry/semconv-ai at a pseudo-version. If you intend to build this submodule standalone, add a replace here or manage via a repository-level go.work so local changes are picked up consistently (currently only the root go.mod includes replaces).

sample-app/.gitignore (1)

1-4: Good safeguard for VCR artefacts; add minimal guidance file

Pattern looks good and prevents leaking raw cassettes. Consider adding testdata/README.md with sanitization rules so future contributors don’t accidentally commit new unsanitized files.

sample-app/go.mod (2)

12-55: Tidy and deduplicate indirects

Run 'go mod tidy' to prune unnecessary indirect dependencies and reduce duplicate packages (e.g., both cenkalti/backoff and cenkalti/backoff/v4 are present). This keeps the module lean and avoids version conflicts.

Command:

  • go mod tidy -v

57-60: Replace directives are fine; consider conditional setup for external consumers

Local replaces are appropriate for this PR. If this sample is consumed outside the mono-repo, document or gate these replaces (e.g., via build tags or separate example module) to avoid confusion.

sample-app/testdata/tool_calling_cassette.yaml (1)

13-15: Avoid brittle headers in cassettes

User-Agent includes the exact client version (alpha.35). Upgrading the SDK may tempt re-recording or cause confusion. Consider filtering User-Agent from recorded headers to make cassettes future-proof.

If using go-vcr, you can configure header filtering before saving the cassette.

traceloop-sdk/sdk_test.go (1)

26-33: Use the public constructor to decouple the test from struct internals

The test manually instantiates Traceloop and fills only two fields.
If the struct gains new required fields, this test will panic silently. Prefer:

tl := sdk.NewClient(config.Config{BaseURL: "...", APIKey: "test-key"})
tl.TracerProviderOverride(tp) // or export the field temporarily

This keeps the test resilient to future changes in Traceloop.

sample-app/tool_calling_test.go (1)

55-56: Disable SDK polling in unit tests

traceloop.Initialize launches the prompt-polling loop which performs network I/O every 5 s.
For a pure unit test it is unnecessary noise and can slow the suite. Consider:

traceloop.SkipPolling = true // or inject a nil/Mock poller
sample-app/tool_calling.go (1)

66-91: Minor duplication between tool definition helpers

createWeatherTool and convertToolsToDTO repeat the same JSON schema.
Returning the schema once and re-using it would cut maintenance effort.

traceloop-sdk/sdk.go (1)

107-128: Duplicate attribute-setting code

setMessagesAttribute and setCompletionsAttribute perform nearly the same work.
Consider merging them with a prefix parameter to reduce drift.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b2b4b4 and 929e4e9.

⛔ Files ignored due to path filters (2)
  • sample-app/go.sum is excluded by !**/*.sum
  • traceloop-sdk/go.sum is excluded by !**/*.sum
📒 Files selected for processing (15)
  • go.mod (1 hunks)
  • sample-app/.gitignore (1 hunks)
  • sample-app/README.md (1 hunks)
  • sample-app/README_testing.md (1 hunks)
  • sample-app/go.mod (1 hunks)
  • sample-app/main.go (1 hunks)
  • sample-app/testdata/tool_calling_cassette.yaml (1 hunks)
  • sample-app/tool_calling.go (1 hunks)
  • sample-app/tool_calling_test.go (1 hunks)
  • traceloop-sdk/dto/tracing.go (2 hunks)
  • traceloop-sdk/go.mod (2 hunks)
  • traceloop-sdk/sdk.go (3 hunks)
  • traceloop-sdk/sdk_test.go (1 hunks)
  • traceloop-sdk/tracing.go (1 hunks)
  • traceloop-sdk/utils.go (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
sample-app/main.go (2)
traceloop-sdk/sdk.go (1)
  • NewClient (30-36)
traceloop-sdk/config/config.go (1)
  • Config (9-14)
sample-app/tool_calling.go (3)
traceloop-sdk/dto/tracing.go (9)
  • ToolCall (21-25)
  • ToolCallFunction (27-30)
  • Tool (16-19)
  • ToolFunction (10-14)
  • Message (3-8)
  • PromptLogAttributes (62-68)
  • Prompt (32-43)
  • Completion (45-48)
  • Usage (56-60)
traceloop-sdk/sdk.go (1)
  • NewClient (30-36)
traceloop-sdk/config/config.go (1)
  • Config (9-14)
traceloop-sdk/sdk_test.go (3)
traceloop-sdk/sdk.go (1)
  • Traceloop (23-28)
traceloop-sdk/config/config.go (1)
  • Config (9-14)
traceloop-sdk/dto/tracing.go (9)
  • PromptLogAttributes (62-68)
  • Prompt (32-43)
  • Tool (16-19)
  • ToolFunction (10-14)
  • Message (3-8)
  • Completion (45-48)
  • ToolCall (21-25)
  • ToolCallFunction (27-30)
  • Usage (56-60)
traceloop-sdk/sdk.go (1)
traceloop-sdk/dto/tracing.go (6)
  • ToolCall (21-25)
  • Message (3-8)
  • Tool (16-19)
  • PromptLogAttributes (62-68)
  • Prompt (32-43)
  • Completion (45-48)
🔇 Additional comments (7)
traceloop-sdk/go.mod (1)

3-5: Toolchain bump: ensure CI and dev envs support Go 1.23

The module declares go 1.23.0 and toolchain go1.23.12. Verify CI uses GOTOOLCHAIN=auto or Go 1.23+ to avoid build surprises, especially since the root module targets go 1.21.

sample-app/main.go (1)

17-21: CLI arg check works; consider using flag parsing and passing context

The "tool-calling" branch is fine for a sample. For robustness:

  • Prefer the standard flag package to allow future flags without breaking arg order.
  • Consider passing ctx into runToolCallingExample for consistent cancellation handling.
  • Ensure runToolCallingExample initializes and shuts down Traceloop on its own, since this branch returns early.

Would you like me to refactor this to use flag and thread ctx through runToolCallingExample?

sample-app/README.md (1)

25-29: Doc-code alignment for TRACELOOP_BASE_URL

README documents TRACELOOP_BASE_URL (optional), but main.go currently hardcodes the BaseURL. Please ensure code reads this env var with fallback to production so the doc remains accurate.

I proposed the corresponding code change in main.go to honor this variable.

sample-app/go.mod (1)

5-10: Confirm need for both OpenAI clients

You're depending on both github.com/openai/openai-go and github.com/sashabaranov/go-openai. If the intent is to use openai-go for tool-calling and keep go-openai for the basic sample, that's fine. Otherwise, drop the unused one to reduce surface area.

Do both samples require separate clients? If not, I can refactor to a single client.

sample-app/testdata/tool_calling_cassette.yaml (1)

6-7: Tool function name “get_weather” is consistent across code, tests, and cassette
All references in sample-app/tool_calling.go, sample-app/tool_calling_test.go, and sample-app/testdata/tool_calling_cassette.yaml use the exact name and schema “get_weather”, so no changes are needed.

sample-app/README_testing.md (1)

19-23: .gitignore correctly configured for VCR cassettes

The sample-app/.gitignore file already ignores all files under testdata/* and explicitly allows only the sanitized cassette:

  • testdata/*
  • !testdata/tool_calling_cassette.yaml

No further changes are needed.

traceloop-sdk/dto/tracing.go (1)

7-8: DTO additions look solid

The added Tool* and ToolCall* structs cleanly extend the model; JSON tags are consistent with OpenAI payloads.

Also applies to: 10-30, 42-43

nirga and others added 3 commits August 9, 2025 19:49
- Resolved merge conflicts between DTO-based tool calling and new workflow API
- Extended new tracing types to support tool calling with ToolCall, Tool, etc.
- Maintained backward compatibility with LogPromptLegacy function
- Integrated both APIs: new workflow-based LogPrompt and legacy DTO-based LogPromptLegacy
- Added tool calling support to new Message and Prompt types
- Fixed function naming conflicts and span parameter issues
- All tool calling tests pass with individual span attributes
- Compatible with both sashabaranov/go-openai and openai/openai-go libraries

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Removed LogPromptLegacy and all DTO helper functions
- Updated tests to use new workflow-based LogPrompt + LogCompletion API
- Simplified tool calling sample to use new API directly
- Updated all sample applications to use new API
- Removed entire dto package - no longer needed
- Preserved all tool calling functionality with individual span attributes
- Maintained JSON serialization for llm.prompts and llm.completions
- Added support for association properties in WorkflowAttributes
- All tests pass with comprehensive tool calling span attributes

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
…ration

- Implement comprehensive tool calling support with individual span attributes
- Add dotenv support for easy API key configuration
- Fix OTLP trace export with proper WithEndpoint/WithURLPath usage
- Restore prompt registry integration in main.go matching original design
- Add automatic https:// URL handling for HTTP client and OTLP exporter
- Update tool calling sample to use new workflow-based API
- Remove all legacy DTO-based APIs in favor of clean workflow implementation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

@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 597a48d in 1 minute and 28 seconds. Click for details.
  • Reviewed 312 lines of code in 6 files
  • Skipped 0 files when reviewing.
  • Skipped posting 3 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. sample-app/go.mod:28
  • Draft comment:
    Added dependency for godotenv v1.5.1. Ensure documentation is updated to reflect the new env loading behavior.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None
2. sample-app/tool_calling.go:192
  • Draft comment:
    When unmarshaling tool call arguments, ensure that the JSON schema remains aligned with the tool definition. Consider adding stricter validation or error messages.
  • 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.
3. traceloop-sdk/tracing.go:19
  • Draft comment:
    Consider using the standard library's URL parsing (net/url) instead of manual string manipulation to sanitize and append a default port. This could handle edge cases (e.g., trailing slashes or malformed URLs) more robustly.
  • 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% The suggestion is reasonable since net/url is the standard way to handle URLs in Go and could handle edge cases better. However, the current implementation is simple and handles the basic cases needed. The code only needs to strip protocols and add a port - it's not doing complex URL parsing. The current approach is readable and maintainable for this specific use case. The current code might fail with URLs containing userinfo sections or URLs with multiple colons. The net/url package would handle these cases correctly. While net/url would be more robust, this code is specifically handling API endpoints which are unlikely to contain userinfo or complex URL structures. The current solution is sufficient for its limited purpose. While using net/url would be more robust, the current implementation is simple, readable, and sufficient for its specific use case. The comment, while technically correct, suggests unnecessary complexity.

Workflow ID: wflow_QFGGQLhbjUITFuud

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

- Remove tool_calling_test.go and VCR testing infrastructure
- Clean up go.mod by removing gopkg.in/dnaeon/go-vcr.v2 dependency
- Remove testdata directory with cassette files
- Simplify codebase by focusing on working examples over test complexity
- Both main and tool-calling examples continue to work perfectly

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

@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 9d4aa6e in 56 seconds. Click for details.
  • Reviewed 265 lines of code in 4 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. sample-app/go.mod:6
  • Draft comment:
    Explicitly adding 'github.com/joho/godotenv' to the main require block is good for clarity. Ensure this dependency is actually used in the runtime rather than just being an indirect requirement.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
2. sample-app/go.mod:9
  • Draft comment:
    Removal of the 'gopkg.in/dnaeon/go-vcr.v2' dependency suggests that HTTP call mocking for tests has been removed. Confirm that any tests relying on it have been replaced or migrated.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% The comment is asking the PR author to confirm that tests relying on a removed dependency have been replaced or migrated. This falls under asking the author to ensure behavior is intended or to double-check things, which is against the rules.
3. sample-app/go.mod:38
  • Draft comment:
    The new dependency 'go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc' is added to support enhanced tracing. This appears appropriate for the new tool calling functionality.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
4. sample-app/testdata/tool_calling_cassette.yaml:1
  • Draft comment:
    The entire cassette file for tool calling tests has been removed. Verify that test coverage for tool calling is maintained elsewhere if needed.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
5. sample-app/tool_calling_test.go:1
  • Draft comment:
    The tool calling test file has been entirely removed. Ensure that there are alternative tests validating this new feature, as tests for tool calling functionality were part of the design.
  • 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_KYh96Y0cLKeDTyOB

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

Copy link

@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: 3

🔭 Outside diff range comments (1)
sample-app/main.go (1)

87-92: Propagate the same context to the OpenAI call

Use ctx instead of context.Background() to propagate cancellations, deadlines, and tracing.

-	resp, err := client.CreateChatCompletion(
-		context.Background(),
-		*request,
-	)
+	resp, err := client.CreateChatCompletion(
+		ctx,
+		*request,
+	)
♻️ Duplicate comments (7)
traceloop-sdk/tracing.go (1)

18-38: Endpoint normalisation is still brittle and drops critical details

The code still strips “http(s)://” with simple prefix checks, losing support for:
http:// endpoints that need WithInsecure() and default port 80
• hosts that already include a path (e.g. /custom/base) – the path is discarded then hard-coded to /v1/traces
• URLs with credentials or query params
A previous review raised exactly this (see earlier discussion) – please switch to proper net/url parsing, preserve Host, detect scheme to add WithInsecure(), and keep non-root Path via WithURLPath.

sample-app/go.mod (2)

3-3: Invalid go directive

go 1.23.0 must be go 1.23.


40-41: OpenTelemetry version mismatch

Core OTel is v1.37.0 while exporter libs remain at v1.22.0 – mixing minors is unsupported and causes panic-time incompatibilities. Align everything to the same minor version (prefer v1.37.0).

traceloop-sdk/sdk.go (3)

148-152: Guard against nil tracerProvider before starting span (prevents panic).

Calling instance.getTracer() dereferences tracerProvider without a nil check. Add a guard to fail fast with a clear error if SDK isn’t initialized.

 func (instance *Traceloop) LogPrompt(ctx context.Context, prompt Prompt, workflowAttrs WorkflowAttributes) (LLMSpan, error) {
+	if instance.tracerProvider == nil {
+		return LLMSpan{}, fmt.Errorf("Traceloop not initialised: tracerProvider nil")
+	}
 	spanName := fmt.Sprintf("%s.%s", prompt.Vendor, prompt.Mode)
 	_, span := instance.getTracer().Start(ctx, spanName)

179-193: Handle json.Marshal errors in LogCompletion and end span on all paths.

Move defer End() to the top and handle marshal errors to prevent silent failures.

-func (llmSpan *LLMSpan) LogCompletion(ctx context.Context, completion Completion, usage Usage) error {
-	// Serialize messages to JSON for main attributes
-	completionsJSON, _ := json.Marshal(completion.Messages)
+func (llmSpan *LLMSpan) LogCompletion(ctx context.Context, completion Completion, usage Usage) error {
+	defer llmSpan.span.End()
+	// Serialize messages to JSON for main attributes
+	completionsJSON, err := json.Marshal(completion.Messages)
+	if err != nil {
+		return fmt.Errorf("marshal completion messages: %w", err)
+	}
 
 	llmSpan.span.SetAttributes(
 		semconvai.LLMResponseModel.String(completion.Model),
 		semconvai.LLMUsageTotalTokens.Int(usage.TotalTokens),
 		semconvai.LLMUsageCompletionTokens.Int(usage.CompletionTokens),
 		semconvai.LLMUsagePromptTokens.Int(usage.PromptTokens),
 		semconvai.LLMCompletions.String(string(completionsJSON)),
 	)
 
 	setMessagesAttribute(llmSpan.span, "llm.completions", completion.Messages)
-
-	defer llmSpan.span.End()
 	return nil
 }

153-171: Handle json.Marshal errors and avoid silent attribute loss in LogPrompt.

Currently json.Marshal errors are ignored, which can silently drop critical attributes. Return an error and avoid leaving an open span.

-	// Serialize messages to JSON for main attributes
-	promptsJSON, _ := json.Marshal(prompt.Messages)
+	// Serialize messages to JSON for main attributes
+	promptsJSON, err := json.Marshal(prompt.Messages)
+	if err != nil {
+		span.End()
+		return LLMSpan{}, fmt.Errorf("marshal prompt messages: %w", err)
+	}
 
 	attrs := []attribute.KeyValue{
 		semconvai.LLMVendor.String(prompt.Vendor),
 		semconvai.LLMRequestModel.String(prompt.Model),
 		semconvai.LLMRequestType.String(prompt.Mode),
 		semconvai.TraceloopWorkflowName.String(workflowAttrs.Name),
 		semconvai.LLMPrompts.String(string(promptsJSON)),
 	}
 
 	// Add association properties if provided
 	for key, value := range workflowAttrs.AssociationProperties {
 		attrs = append(attrs, attribute.String("traceloop.association.properties."+key, value))
 	}
 
 	span.SetAttributes(attrs...)
 	setMessagesAttribute(span, "llm.prompts", prompt.Messages)
 	setToolsAttribute(span, prompt.Tools)

Optional: You’re setting both the full prompts JSON and per-message content/role. Consider dropping one or truncating to respect OTel attribute size limits.

sample-app/main.go (1)

33-35: Honor TRACELOOP_BASE_URL env var with sensible default

Allow overriding the SDK base URL via TRACELOOP_BASE_URL for testing/self-hosting while keeping the default implicit in the SDK.

Apply:

-	traceloop, err := sdk.NewClient(ctx, sdk.Config{
-		APIKey: os.Getenv("TRACELOOP_API_KEY"),
-	})
+	// Allow overriding BaseURL via env for testing and self-hosting scenarios.
+	baseURL := os.Getenv("TRACELOOP_BASE_URL")
+	cfg := sdk.Config{
+		APIKey: os.Getenv("TRACELOOP_API_KEY"),
+	}
+	// Only set BaseURL if provided, let SDK default otherwise.
+	if baseURL != "" {
+		cfg.BaseURL = baseURL
+	}
+	traceloop, err := sdk.NewClient(ctx, cfg)

If sdk.Config doesn’t expose BaseURL, keep cfg as-is and skip setting it. To verify:

#!/bin/bash
# Check if BaseURL exists in traceloop-sdk Config
ast-grep --pattern $'type Config struct {\n  $$$\n  BaseURL $_\n  $$$\n}'
# Also locate the Config type definition for manual inspection
rg -n \"type Config struct\" -A 20 | sed -n '1,120p'
🧹 Nitpick comments (11)
sample-app/go.mod (1)

6-9: Two different OpenAI SDKs inflate the build

Both github.com/openai/openai-go and github.com/sashabaranov/go-openai are required. Unless the sample app truly needs both, keep a single SDK to cut binary size and avoid cognitive overhead.

sample-app/tool_calling.go (2)

11-13: Inconsistent SDK usage

Importing the new official openai-go SDK here while the rest of the sample app uses go-openai leads to two divergent APIs in one repo. Standardise on one SDK for maintainability.


192-199: Missing default for temperature unit

If unit is empty, getWeather prints a dangling degree symbol (72°). Either default to "F"/"fahrenheit" or surface a validation error before calling getWeather.

traceloop-sdk/sdk.go (3)

80-92: Consider truncation/redaction for message content to meet OTel limits and privacy.

content may be large and/or contain PII. Add truncation (e.g., to 4–8KB) and optional redaction hooks to avoid exceeding attribute limits and leaking sensitive data.


96-106: Guard function-specific fields by type and consider truncating arguments.

For non-"function" tool calls, name/arguments may be empty or irrelevant. Also, arguments can be large/PII.

 func setToolCallsAttribute(span apitrace.Span, messagePrefix string, toolCalls []ToolCall) {
 	for i, toolCall := range toolCalls {
 		toolCallPrefix := fmt.Sprintf("%s.tool_calls.%d", messagePrefix, i)
-		span.SetAttributes(
-			attribute.String(toolCallPrefix+".id", toolCall.ID),
-			attribute.String(toolCallPrefix+".type", toolCall.Type),
-			attribute.String(toolCallPrefix+".name", toolCall.Function.Name),
-			attribute.String(toolCallPrefix+".arguments", toolCall.Function.Arguments),
-		)
+		span.SetAttributes(
+			attribute.String(toolCallPrefix+".id", toolCall.ID),
+			attribute.String(toolCallPrefix+".type", toolCall.Type),
+		)
+		if toolCall.Type == "function" {
+			span.SetAttributes(
+				attribute.String(toolCallPrefix+".name", toolCall.Function.Name),
+				attribute.String(toolCallPrefix+".arguments", toolCall.Function.Arguments), // consider truncation/redaction
+			)
+		}
 	}
 }

110-131: Don’t print to stdout from SDK; use log.Printf (or return error) for marshal failures.

Printing directly to stdout is noisy for library consumers.

-			if err == nil {
+			if err == nil {
 				span.SetAttributes(
 					attribute.String(prefix+".parameters", string(parametersJSON)),
 				)
 			} else {
-				fmt.Printf("Failed to marshal tool parameters for %s: %v\n", tool.Function.Name, err)
+				log.Printf("Failed to marshal tool parameters for %s: %v", tool.Function.Name, err)
 			}
sample-app/main.go (5)

56-64: Preallocate slice for prompt messages

Micro-optimization and clarity; avoids re-allocations as the length is known.

-	// Convert to our format for logging
-	var promptMsgs []sdk.Message
+	// Convert to our format for logging
+	promptMsgs := make([]sdk.Message, 0, len(request.Messages))
 	for i, message := range request.Messages {
 		promptMsgs = append(promptMsgs, sdk.Message{
 			Index:   i,
 			Content: message.Content,
 			Role:    message.Role,
 		})
 	}

98-106: Preallocate slice for completion messages

Minor efficiency improvement.

-	// Convert response to our format for logging
-	var completionMsgs []sdk.Message
+	// Convert response to our format for logging
+	completionMsgs := make([]sdk.Message, 0, len(resp.Choices))
 	for _, choice := range resp.Choices {
 		completionMsgs = append(completionMsgs, sdk.Message{
 			Index:   choice.Index,
 			Content: choice.Message.Content,
 			Role:    choice.Message.Role,
 		})
 	}

21-24: Prefer flag/subcommands over manual os.Args parsing

Using the flag package (or subcommands) provides usage help and safer arg parsing. Optional, since this is a sample.

Example:

cmd := flag.String("cmd", "", "command to run (tool-calling)")
flag.Parse()
if *cmd == "tool-calling" {
    runToolCallingExample()
    return
}

31-35: Fail fast if required env vars are missing

Surface clear errors early for a better developer experience.

 func workflowExample() {
 	ctx := context.Background()
 
-	traceloop, err := sdk.NewClient(ctx, sdk.Config{
+	if os.Getenv("TRACELOOP_API_KEY") == "" {
+		log.Println("TRACELOOP_API_KEY is not set")
+		return
+	}
+	if os.Getenv("OPENAI_API_KEY") == "" {
+		log.Println("OPENAI_API_KEY is not set")
+		return
+	}
+	traceloop, err := sdk.NewClient(ctx, sdk.Config{
 		APIKey: os.Getenv("TRACELOOP_API_KEY"),
 	})

37-38: Use log.Printf for errors for consistent logging

Optional style nit: use log.Printf instead of fmt.Printf for errors to include timestamps and standardize logs.

Also applies to: 52-54, 83-85, 94-96, 118-120

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 929e4e9 and 597a48d.

⛔ Files ignored due to path filters (4)
  • go.work is excluded by !**/*.work
  • go.work.sum is excluded by !**/*.sum
  • sample-app/go.sum is excluded by !**/*.sum
  • traceloop-sdk/go.sum is excluded by !**/*.sum
📒 Files selected for processing (11)
  • sample-app/go.mod (1 hunks)
  • sample-app/main.go (2 hunks)
  • sample-app/tool_calling.go (1 hunks)
  • sample-app/tool_calling_test.go (1 hunks)
  • sample-app/workflow_example.go (1 hunks)
  • traceloop-sdk/go.mod (2 hunks)
  • traceloop-sdk/sdk.go (3 hunks)
  • traceloop-sdk/sdk_test.go (1 hunks)
  • traceloop-sdk/tracing.go (1 hunks)
  • traceloop-sdk/tracing_types.go (3 hunks)
  • traceloop-sdk/utils.go (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • sample-app/workflow_example.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • traceloop-sdk/utils.go
  • sample-app/tool_calling_test.go
  • traceloop-sdk/sdk_test.go
  • traceloop-sdk/go.mod
🔇 Additional comments (1)
traceloop-sdk/sdk.go (1)

80-92: Ensure unique attribute prefixes to avoid collisions

We couldn’t find any code that sets or enforces uniqueness of Message.Index in the repository. If Index isn’t guaranteed unique and sequential, using it for attribute names risks naming collisions at telemetry time.

Please verify one of the following approaches:

  • Use the loop index (i) when building attrsPrefix to ensure no duplicates:
    for i, message := range messages {
        attrsPrefix := fmt.Sprintf("%s.%d", prefix, i)
        …
    }
  • Or document and enforce that every Message.Index is set uniquely and incrementally before calling setMessagesAttribute.

Key locations:

  • traceloop-sdk/sdk.go → setMessagesAttribute
  • traceloop-sdk/tracing_types.go:3 → type Message struct { Index int … }

Comment on lines 122 to +123
fmt.Println(resp.Choices[0].Message.Content)
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Guard against empty choices

Avoid a potential panic if the API returns zero choices.

-	fmt.Println(resp.Choices[0].Message.Content)
-}
+	if len(resp.Choices) > 0 {
+		fmt.Println(resp.Choices[0].Message.Content)
+	} else {
+		log.Println("No choices returned by OpenAI")
+	}
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fmt.Println(resp.Choices[0].Message.Content)
}
}
// Guard against empty choices to avoid a panic
if len(resp.Choices) > 0 {
fmt.Println(resp.Choices[0].Message.Content)
} else {
log.Println("No choices returned by OpenAI")
}
}
🤖 Prompt for AI Agents
In sample-app/main.go around lines 122 to 123, the code directly accesses
resp.Choices[0] without checking if the Choices slice is empty, which can cause
a panic. Add a guard condition to check if resp.Choices has at least one element
before accessing resp.Choices[0].Message.Content, and handle the empty case
appropriately to prevent runtime errors.

Comment on lines +45 to +48
type Tool struct {
Type string `json:"type"`
Function ToolFunction `json:"function,omitempty"`
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

omitempty ineffective on value-type Function field

Because Tool.Function is a value (not a pointer), JSON encoding will emit an empty {} even when unset. If you intend the field to disappear entirely, make it *ToolFunction or use json:",omitempty" on a pointer.

🤖 Prompt for AI Agents
In traceloop-sdk/tracing_types.go around lines 45 to 48, the Tool.Function field
is a value type, so the `omitempty` tag does not prevent it from being
serialized as an empty object. To fix this, change the type of Function from
ToolFunction to a pointer *ToolFunction so that when it is nil, it will be
omitted from the JSON output as intended.

- Remove README_testing.md which documented the deleted VCR test infrastructure
- Keep sdk_test.go which provides valuable unit testing with in-memory tracing
- SDK unit test validates all 22 span attributes including tool calling features
- Test suite now focused on fast, reliable unit tests without external dependencies

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

@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 b565278 in 32 seconds. Click for details.
  • Reviewed 88 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 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. sample-app/README_testing.md:1
  • Draft comment:
    The entire README_testing.md file was removed. This file contained important instructions for testing tool calling features (using go-vcr recordings, integration tests, and security sanitization details). If these details are relocated, please update the main documentation with a reference to the new location. Otherwise, retaining essential testing guidelines would benefit developers.
  • 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_hn063Y8j4vblpjFm

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

Copy link

@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: 2

♻️ Duplicate comments (2)
sample-app/go.mod (2)

3-3: Use major.minor in the go directive (no patch).

go 1.23.0 is invalid; the directive must be major.minor only.

Apply:

-go 1.23.0
+go 1.23

38-44: Align OpenTelemetry exporters to v1.37.0 to match core packages.

Core OTel deps are v1.37.0, but otlptrace exporters are v1.22.0. Mismatches can cause subtle runtime/type issues. Align exporters to v1.37.0.

-	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.22.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.22.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 597a48d and b565278.

⛔ Files ignored due to path filters (1)
  • sample-app/go.sum is excluded by !**/*.sum
📒 Files selected for processing (1)
  • sample-app/go.mod (1 hunks)

Comment on lines +57 to +59
replace github.com/traceloop/go-openllmetry/traceloop-sdk => ../traceloop-sdk

replace github.com/traceloop/go-openllmetry/semconv-ai => ../semconv-ai
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Prefer a go.work workspace over committing replace directives.

Local replaces are fine for development, but a go.work at the repo root is cleaner for multi-module repos and avoids leaking local paths in committed go.mod files.

Check if a workspace file exists:

If adopting go.work, you can remove these replace lines and add the modules via:

  • go work init ./traceloop-sdk ./semconv-ai ./sample-app

🏁 Script executed:

#!/bin/bash
fd -a go.work

Length of output: 73


To confirm that the workspace already includes the local modules (so we can safely drop those replace lines), let’s inspect the contents of your go.work:


🏁 Script executed:

#!/bin/bash
echo "=== go.work ==="
cat go.work

Length of output: 112


Remove redundant replace directives in sample-app/go.mod

Since your go.work already includes sample-app, semconv-ai, and traceloop-sdk, you can drop the local replace lines to avoid leaking file paths into committed go.mod files.

• File: sample-app/go.mod
Lines: 57–59
Diff:

- replace github.com/traceloop/go-openllmetry/traceloop-sdk => ../traceloop-sdk
- replace github.com/traceloop/go-openllmetry/semconv-ai => ../semconv-ai
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
replace github.com/traceloop/go-openllmetry/traceloop-sdk => ../traceloop-sdk
replace github.com/traceloop/go-openllmetry/semconv-ai => ../semconv-ai
🤖 Prompt for AI Agents
In sample-app/go.mod at lines 57 to 59, remove the local replace directives for
github.com/traceloop/go-openllmetry/traceloop-sdk and
github.com/traceloop/go-openllmetry/semconv-ai because these modules are already
included in the go.work file. Deleting these replace lines will prevent leaking
local file paths into the committed go.mod file.

- Remove obsolete traceloop-sdk/dto/ directory causing type redeclaration errors
- Clean up root go.mod by removing unused dependencies
- Disable Go setup caching in CI to avoid "Dependencies file not found" errors
- CI now properly builds all modules without conflicts
- All tests pass locally including SDK unit tests

Fixes GitHub Actions build failures with variable redeclaration errors.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

@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 fddb6dd in 39 seconds. Click for details.
  • Reviewed 100 lines of code in 3 files
  • Skipped 0 files when reviewing.
  • Skipped posting 3 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. .github/workflows/ci.yml:22
  • Draft comment:
    Explicitly disabling caching with 'cache: false' for the Go setup step can slow down builds. Confirm that caching is intentionally disabled and consider adding a comment explaining the rationale.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 30% <= threshold 50% The comment is asking the PR author to confirm their intention of disabling caching, which violates the rule against asking for confirmation of intention. However, it also provides a suggestion to add a comment explaining the rationale, which is a specific code suggestion. The comment is partially useful but mostly violates the rules.
2. go.mod:2
  • Draft comment:
    The 'require' block for the traceloop-sdk and semconv-ai modules has been removed. Ensure that this change is intentional and that dependency resolution still works as expected for downstream users.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is asking the PR author to ensure that the change is intentional and that dependency resolution works, which violates the rules against asking for confirmation or ensuring behavior. It does not provide a specific suggestion or point out a specific issue.
3. traceloop-sdk/dto/tracing.go:1
  • Draft comment:
    The entire file containing DTO definitions (e.g., Message, ToolCall, and related types) has been removed. Confirm that these types are no longer needed or have been relocated, to avoid breaking compatibility with existing integrations.
  • 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_mEe7F72CSpYH6jh2

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

- Add GOWORK=off to all CI steps to disable workspace mode
- This allows proper test discovery in each module independently
- SDK tests now run correctly in CI (were showing [no test files])
- Build and install steps also use GOWORK=off for consistency

Without this fix, Go workspace was interfering with test file discovery
causing all modules to show [no test files] even when tests exist.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

@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 6426159 in 30 seconds. Click for details.
  • Reviewed 16 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 3 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. .github/workflows/ci.yml:24
  • Draft comment:
    Ensure that disabling Go workspace (GOWORK=off) in dependency installation is intentional. Consider if using 'go mod download' or 'go mod tidy' might be more robust.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None
2. .github/workflows/ci.yml:26
  • Draft comment:
    Check that disabling workspace for the build step suits all module scenarios; verify multiple modules are handled as expected.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None
3. .github/workflows/ci.yml:28
  • Draft comment:
    For the Test step, ensure 'GOWORK=off' doesn't inadvertently affect test discovery in multi-module setups.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None

Workflow ID: wflow_iN9GaFsMpnOvBsNg

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

This simple test should help identify why CI shows [no test files]
when tests clearly exist and work locally. If this test is also
not detected by CI, there's an issue with the CI environment setup.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

@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 d61145b in 27 seconds. Click for details.
  • Reviewed 14 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. traceloop-sdk/simple_test.go:7
  • Draft comment:
    Add a newline at end of file for POSIX compliance.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None
2. traceloop-sdk/simple_test.go:5
  • Draft comment:
    Consider adding assertions to the test to verify behavior beyond logging.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None

Workflow ID: wflow_mhayXD6ACwCIfMUG

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

CRITICAL: pull_request_target was causing CI to test main branch code
instead of the actual PR changes, explaining all our CI failures.

Issues with pull_request_target:
- Security risk: Runs with write permissions on target repo
- Wrong code: Tests target branch (main) instead of PR branch
- Stale results: Our fixes weren't being tested at all

With pull_request:
- Tests the actual PR code with our fixes
- No unnecessary write permissions
- Proper CI validation of proposed changes

This should immediately fix all CI test discovery issues.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

@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 78c610c in 1 minute and 19 seconds. Click for details.
  • Reviewed 12 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 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. .github/workflows/ci.yml:3
  • Draft comment:
    Changing the event trigger from 'pull_request_target' to 'pull_request' alters the workflow's security context. Ensure this is intentional—if the build requires secrets (or elevated privileges), using 'pull_request' might restrict access for PRs from forks.
  • 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 is technically correct about the security context difference between pull_request and pull_request_target. However, this workflow appears to be a basic CI pipeline that doesn't use any secrets or require special permissions. The change to pull_request is actually safer by default. The comment is asking for verification without clear evidence of a problem. I could be missing some hidden secrets or permissions that aren't visible in this file. There could be environment variables defined elsewhere. Even if there were hidden secrets, the change to pull_request is the safer option by default. If secrets were needed, the workflow would fail immediately, making it an obvious issue that doesn't need a comment. Delete this comment. It asks for verification without evidence of an actual problem, and the change appears to be an improvement in security posture.

Workflow ID: wflow_MqLszzqe0JMqzjeN

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

Copy link

@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)
traceloop-sdk/simple_test.go (1)

5-7: If you keep TestSimple, at least mark it as parallel/placeholder to reduce noise

If this stays as a placeholder, run it in parallel and skip with a TODO to avoid inflating green test counts without value.

 func TestSimple(t *testing.T) {
-	t.Log("Simple test works")
+	t.Parallel()
+	t.Skip("TODO: replace with meaningful assertions")
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6426159 and d61145b.

📒 Files selected for processing (1)
  • traceloop-sdk/simple_test.go (1 hunks)

Comment on lines 1 to 7
package traceloop

import "testing"

func TestSimple(t *testing.T) {
t.Log("Simple test works")
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace no-op test with an Example doc test or add real assertions

This test only logs and provides no verification signal. Prefer converting it to an Example (which doubles as documentation and a test) or expand with real assertions. Example conversion keeps it lightweight and meaningful.

Apply this diff to convert it into an Example:

-package traceloop
+package traceloop_test

-import "testing"
+import "fmt"

-func TestSimple(t *testing.T) {
-	t.Log("Simple test works")
-}
+func Example() {
+	fmt.Println("Simple test works")
+	// Output: Simple test works
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
package traceloop
import "testing"
func TestSimple(t *testing.T) {
t.Log("Simple test works")
}
package traceloop_test
import "fmt"
func Example() {
fmt.Println("Simple test works")
// Output: Simple test works
}
🤖 Prompt for AI Agents
In traceloop-sdk/simple_test.go lines 1 to 7, the current test only logs a
message without any assertions, making it ineffective as a test. Replace the
TestSimple function with an ExampleSimple function that demonstrates usage and
serves as a documentation test, or alternatively add real assertions to verify
expected behavior. This change will make the test meaningful and useful for both
testing and documentation purposes.

ROOT CAUSE: OpenTelemetry v1.37.0 requires Go 1.23+, but CI was testing Go 1.18-1.21

Issues fixed:
- "invalid go version '1.23.0': must match format 1.23"
- "unknown directive: toolchain" (not supported in older Go)
- "go.opentelemetry.io/[email protected] requires go >= 1.23.0"

Changes:
- Update CI matrix to test Go 1.22, 1.23, 1.24 (current supported versions)
- Fix go.mod format: use "1.23" not "1.23.0" for compatibility
- Remove toolchain directive from go.mod files
- Update go.work to use Go 1.23
- Remove debugging simple_test.go

CI should now pass with proper test execution and no version conflicts.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

@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 84be527 in 1 minute and 9 seconds. Click for details.
  • Reviewed 101 lines of code in 6 files
  • Skipped 0 files when reviewing.
  • Skipped posting 6 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. .github/workflows/ci.yml:14
  • Draft comment:
    CI workflow: Updated Go version matrix now only tests 1.21, 1.22, and 1.23. Ensure that dropping older versions is intentional and aligns with minimum version requirements.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 40% <= threshold 50% The comment is asking the PR author to ensure that dropping older versions is intentional. This violates the rule against asking the author to confirm their intention. However, it does point out a specific change in the CI workflow that could be important to address, but the phrasing needs to be more about confirming the intention rather than ensuring it.
2. go.work:1
  • Draft comment:
    go.work: Changed Go version format to '1.23' and added new modules (semconv-ai, traceloop-sdk) to the workspace. Confirm that module paths and replacements correctly reflect project structure.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% The comment is asking the PR author to confirm that module paths and replacements correctly reflect the project structure. This falls under asking the author to confirm their intention or to double-check things, which is against the rules. Therefore, this comment should be removed.
3. go.work.sum:4
  • Draft comment:
    go.work.sum: Several new dependency entries (e.g., Azure SDK packages, golang-jwt, godebug, pkg/browser, objx) have been added. Verify that these dependencies are necessary and free of known vulnerabilities.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is asking the PR author to verify the necessity and security of new dependencies, which falls under the rule of not asking the author to double-check things. It doesn't provide a specific suggestion or point out a specific issue with the code.
4. sample-app/go.mod:3
  • Draft comment:
    sample-app/go.mod: Updated Go version shorthand from '1.23.0' to '1.23'. Also note the inclusion of an alpha version of the OpenAI Go client; ensure its stability for production use.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% The comment is purely informative about the Go version change and the inclusion of an alpha version of a library. It does not provide a specific suggestion or ask for a specific test to be written. It also mentions ensuring stability, which is against the rules.
5. traceloop-sdk/go.mod:1
  • Draft comment:
    traceloop-sdk/go.mod: Changed Go version format and removed the toolchain directive. Confirm that removal of 'toolchain go1.23.12' is intentional and doesn't affect reproducible builds.
  • Reason this comment was not posted:
    Comment looked like it was already resolved.
6. traceloop-sdk/simple_test.go:1
  • Draft comment:
    traceloop-sdk/simple_test.go: The simple test file has been removed. Consider adding more comprehensive tests for the new tool calling functionality to maintain coverage.
  • 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_EwJaLfEeOIpXKtJD

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

Complete the CI matrix update that was missed in the previous commit.
Now testing Go versions 1.22, 1.23, and 1.24 for comprehensive coverage.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

@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 0276b21 in 31 seconds. Click for details.
  • Reviewed 13 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 1 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. .github/workflows/ci.yml:14
  • Draft comment:
    Ensure dropping Go 1.21 is intentional and that all dependencies/code are compatible with Go 1.24. This update might affect backward compatibility if older versions are needed.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% The comment is asking the PR author to ensure that dropping Go 1.21 is intentional and that all dependencies/code are compatible with Go 1.24. It also mentions potential backward compatibility issues. This falls under asking the author to confirm their intention and ensure compatibility, which violates the rules.

Workflow ID: wflow_yEZIjCkQVEX54rIi

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

Copy link

@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: 2

♻️ Duplicate comments (3)
sample-app/go.mod (3)

7-8: Two OpenAI SDKs present; confirm intent or trim

Both github.com/openai/openai-go (alpha) and github.com/sashabaranov/go-openai are required. Keep both only if intentionally demonstrating alternatives; otherwise, drop one to reduce bloat and confusion. If you keep both, call this out explicitly in the sample README.


38-44: Align OpenTelemetry exporters to v1.37.0

Your core OTel deps are v1.37.0 while exporters are v1.22.0. Mismatches can cause subtle runtime issues. Align exporters to the same minor version.

-	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.22.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.22.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect

After bumping, run:


57-59: Prefer workspace over committed local replaces

Since the repo already uses go.work including these modules, drop local replace directives to avoid leaking paths and reduce churn.

-replace github.com/traceloop/go-openllmetry/traceloop-sdk => ../traceloop-sdk
-
-replace github.com/traceloop/go-openllmetry/semconv-ai => ../semconv-ai
🧹 Nitpick comments (6)
sample-app/go.mod (1)

9-10: Pseudo-version placeholder for traceloop-sdk

v0.0.0-00010101000000-000000000000 is a placeholder and is ignored under go.work. If the sample is ever built outside the workspace, pin to a real version (tag or commit-derived pseudo-version).

.github/workflows/ci.yml (5)

3-4: Good move switching to pull_request; consider additional event types.

Switching away from pull_request_target reduces risk. Consider including reopened (and optionally ready_for_review) to ensure CI runs on those updates too.

Example:

 on:
-  pull_request:
-    types: [opened, synchronize]
+  pull_request:
+    types: [opened, synchronize, reopened]

14-14: Verify Go 1.24 availability; prefer patch-tracking specifiers.

If 1.24 isn't GA or supported by setup-go yet, the matrix will fail. Prefer "1.22.x"/"1.23.x" to always pick latest patches.

-        go-version: ["1.22", "1.23", "1.24"]
+        go-version: ["1.22.x", "1.23.x"]

If 1.24 is confirmed available, use "1.24.x".


22-22: Optional: enable module cache for faster CI across matrix runs.

cache: false is safe but slow. Consider enabling cache with a multi-module dependency path.

-          cache: false
+          cache: true
+          cache-dependency-path: "**/go.sum"

26-26: Build all packages in each module.

go build . only targets the current package; building ./... ensures all subpackages compile.

-        run: GOWORK=off find . -name go.mod -execdir go build . \;
+        run: GOWORK=off find . -name go.mod -execdir go build ./... \;

28-28: Harden tests with race detector and shuffling.

Catches data races and flaky order dependencies.

-        run: GOWORK=off find . -name go.mod -execdir go test ./... \;
+        run: GOWORK=off find . -name go.mod -execdir go test -race -shuffle=on ./... \;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 78c610c and 0276b21.

⛔ Files ignored due to path filters (2)
  • go.work is excluded by !**/*.work
  • go.work.sum is excluded by !**/*.sum
📒 Files selected for processing (3)
  • .github/workflows/ci.yml (2 hunks)
  • sample-app/go.mod (1 hunks)
  • traceloop-sdk/go.mod (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • traceloop-sdk/go.mod
🧰 Additional context used
🪛 actionlint (1.7.7)
.github/workflows/ci.yml

19-19: the runner of "actions/setup-go@v4" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

Comment on lines 19 to 21
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go-version }}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Upgrade actions/setup-go to v5 (actionlint warning).

actionlint flags v4 as too old on current runners. Upgrade to v5.

-      - name: Setup Go ${{ matrix.go-version }}
-        uses: actions/setup-go@v4
+      - name: Setup Go ${{ matrix.go-version }}
+        uses: actions/setup-go@v5
         with:
           go-version: ${{ matrix.go-version }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go-version }}
- name: Setup Go ${{ matrix.go-version }}
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
🧰 Tools
🪛 actionlint (1.7.7)

19-19: the runner of "actions/setup-go@v4" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
In .github/workflows/ci.yml around lines 19 to 21, the setup-go action is using
version v4, which actionlint flags as outdated. Update the version from v4 to v5
by changing the uses line to actions/setup-go@v5 to comply with current runner
standards and remove the warning.

- name: Install dependencies
run: find . -name go.mod -execdir go get . \;
run: GOWORK=off find . -name go.mod -execdir go get . \;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace go get with go mod download/verify to avoid mutating go.mod in CI.

go get . can modify go.mod/go.sum and is discouraged for installation in recent Go. Use download/verify instead.

-        run: GOWORK=off find . -name go.mod -execdir go get . \;
+        run: GOWORK=off find . -name go.mod -execdir sh -c 'go mod download && go mod verify' \;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
run: GOWORK=off find . -name go.mod -execdir go get . \;
run: GOWORK=off find . -name go.mod -execdir sh -c 'go mod download && go mod verify' \;
🤖 Prompt for AI Agents
In .github/workflows/ci.yml at line 24, replace the command using 'go get .'
with 'go mod download' or 'go mod verify' to avoid modifying go.mod or go.sum
files during CI runs. This change prevents unintended mutations of module files
by ensuring dependencies are only downloaded or verified without altering the
module definitions.

Copy link

@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 00842b0 in 1 minute and 37 seconds. Click for details.
  • Reviewed 68 lines of code in 5 files
  • Skipped 0 files when reviewing.
  • Skipped posting 3 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. go.mod:7
  • Draft comment:
    Consider documenting the reason for the new replace directive for the semconv-ai module. Local replacement (replace github.com/traceloop/go-openllmetry/semconv-ai => ./semconv-ai) is useful for development but should be clearly explained in the README to avoid confusion during dependency management.
  • 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. go.work.sum:31
  • Draft comment:
    There is a version mismatch for the github.com/google/go-cmp dependency. The go.work.sum file lists v0.6.0 while semconv-ai/go.sum uses v0.7.0. Aligning these versions can prevent potential dependency resolution issues.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 0% vs. threshold = 50% According to the rules, we should NOT comment on dependency changes or library versions. The rules explicitly state to ignore dependency-related issues. While there is a real version mismatch, managing dependencies is outside the scope of what these comments should address. The version mismatch could potentially cause real issues in the build. Maybe this is important enough to be an exception to the dependency rule? No - the rules are very clear about not commenting on dependencies. If there are dependency issues, they will be caught by the build system or dependency management tools. Delete this comment as it violates the rule about not commenting on dependency changes or library versions.
3. semconv-ai/go.mod:1
  • Draft comment:
    Typo in the module path: "go-openllmetry" appears to be a misspelling. Did you mean "go-opentelemetry"?
  • Reason this comment was not posted:
    Comment was on unchanged code.

Workflow ID: wflow_X0JiDIaghBTfrZXn

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

- Fix URL construction in utils.go using url.JoinPath for robust path joining
- Remove redundant JSON serialization of messages in span attributes
- Remove unnecessary sleep from main.go workflow example
- Add OpenAI SDK clarification to sample-app README

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

@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 7952b5a in 1 minute and 14 seconds. Click for details.
  • Reviewed 94 lines of code in 4 files
  • Skipped 0 files when reviewing.
  • Skipped posting 4 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. sample-app/main.go:39
  • Draft comment:
    Removed fixed delay (time.Sleep) for prompt registry population. Ensure that the prompt registry is fully initialized before calling GetOpenAIChatCompletionRequest to avoid potential race conditions.
  • 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 sleep was likely added as a hack/workaround. Without seeing the internals of the SDK, we can't know if removing it will cause issues. The SDK should handle its own initialization properly. The comment is speculative and asks for verification without providing concrete evidence of an issue. The sleep might have been added due to a real race condition that was discovered through testing. Removing it could reintroduce that issue. If there was a real race condition, it should be handled properly in the SDK itself, not with arbitrary sleeps in client code. The comment doesn't provide evidence of actual issues. Delete the comment as it's speculative and asks for verification without concrete evidence of an issue. If there are initialization problems, they should surface in testing.
2. traceloop-sdk/sdk.go:150
  • Draft comment:
    Refactored logging: JSON serialization of messages was removed in favor of setting individual message attributes via setMessagesAttribute. Confirm that losing the aggregated JSON view does not affect debugging or trace analysis.
  • 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.
3. traceloop-sdk/utils.go:17
  • Draft comment:
    Using url.JoinPath to construct the full URL is a robust improvement. Consider replacing fmt.Printf with a structured logging approach for better consistency in error handling.
  • Reason this comment was not posted:
    Confidence changes required: 33% <= threshold 50% None
4. sample-app/README.md:7
  • Draft comment:
    The README improvements clearly document the two OpenAI SDK options and the tool calling sample. Documentation is informative and well-organized.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None

Workflow ID: wflow_2TqSxj2P6qlHbjQz

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

@nirga nirga merged commit e776972 into main Aug 10, 2025
8 checks passed
@nirga nirga deleted the tool-calling branch August 10, 2025 15:14
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