Skip to content

fixes costing and token counts for streaming requests - #528

Merged
akshaydeo merged 1 commit into
mainfrom
09-28-fixes_costing_and_token_counts_for_streaming_requests
Sep 29, 2025
Merged

fixes costing and token counts for streaming requests#528
akshaydeo merged 1 commit into
mainfrom
09-28-fixes_costing_and_token_counts_for_streaming_requests

Conversation

@akshaydeo

@akshaydeo akshaydeo commented Sep 28, 2025

Copy link
Copy Markdown
Contributor

Summary

Improves token usage tracking in OpenAI streaming responses and expands OpenRouter test coverage with additional model tests.

Changes

  • Fixed token usage calculation in OpenAI streaming responses by properly accumulating usage data when it arrives in multiple chunks
  • Enhanced streaming tests to validate token usage information throughout the stream and in final responses
  • Added comprehensive tests for Anthropic Claude and Meta Llama models via OpenRouter
  • Removed the requirement for an OpenRouter API key in tests to allow CI to run these tests

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (Next.js)
  • Docs

How to test

Run the OpenRouter tests to verify proper token usage tracking and model support:

# Run all OpenRouter tests
go test -v ./tests/core-providers -run TestOpenRouter

# Run specific model tests
go test -v ./tests/core-providers -run TestOpenRouterAnthropic
go test -v ./tests/core-providers -run TestOpenRouterMetaLlama

Breaking changes

  • Yes
  • No

Related issues

Fixes issues with token usage tracking in streaming responses where usage information was being overwritten instead of accumulated.

Security considerations

No security implications.

Checklist

  • I added/updated tests where appropriate
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@coderabbitai

coderabbitai Bot commented Sep 28, 2025

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Allow deleting custom providers from the UI.
  • Bug Fixes

    • Accurate token counts for streaming responses.
    • Streaming errors now display in the UI instead of staying “processing.”
    • Hide “Response” when an error is present in log details.
    • More reliable streaming error handling and improved error logging.
    • Safer serialization of error details.
  • Tests

    • Added comprehensive OpenRouter provider scenarios.
  • Documentation

    • Changelogs updated.
  • Chores

    • Version bumps across core, framework, transports, and plugins.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title succinctly and accurately captures the central change of fixing cost and token counting logic for streaming requests, using clear and specific phrasing that aligns with the main code modifications while avoiding extraneous detail or vague language.
Description Check ✅ Passed The pull request description adheres to the repository template by providing a clear summary, detailed change list, type of change, affected areas, testing instructions, breaking change indicator, related issues, security considerations, and a checklist, making it comprehensive and well-structured with only optional UI screenshots omitted which are not applicable here.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 568f1bb and 44990dc.

📒 Files selected for processing (30)
  • core/bifrost.go (1 hunks)
  • core/changelog.md (1 hunks)
  • core/providers/openai.go (1 hunks)
  • core/version (1 hunks)
  • framework/changelog.md (1 hunks)
  • framework/logstore/sqlite.go (1 hunks)
  • framework/logstore/tables.go (1 hunks)
  • framework/version (1 hunks)
  • plugins/governance/changelog.md (1 hunks)
  • plugins/governance/version (1 hunks)
  • plugins/jsonparser/changelog.md (1 hunks)
  • plugins/jsonparser/version (1 hunks)
  • plugins/logging/changelog.md (1 hunks)
  • plugins/logging/main.go (1 hunks)
  • plugins/logging/operations.go (4 hunks)
  • plugins/logging/streaming.go (6 hunks)
  • plugins/maxim/changelog.md (1 hunks)
  • plugins/maxim/version (1 hunks)
  • plugins/mocker/changelog.md (1 hunks)
  • plugins/mocker/version (1 hunks)
  • plugins/semanticcache/changelog.md (1 hunks)
  • plugins/semanticcache/version (1 hunks)
  • plugins/telemetry/changelog.md (1 hunks)
  • plugins/telemetry/version (1 hunks)
  • tests/core-providers/openrouter_test.go (1 hunks)
  • tests/core-providers/scenarios/chat_completion_stream.go (7 hunks)
  • transports/bifrost-http/handlers/logging.go (1 hunks)
  • transports/changelog.md (1 hunks)
  • transports/version (1 hunks)
  • ui/app/logs/views/logDetailsSheet.tsx (1 hunks)

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

akshaydeo commented Sep 28, 2025

Copy link
Copy Markdown
Contributor Author

@akshaydeo
akshaydeo marked this pull request as ready for review September 28, 2025 12:17
@akshaydeo
akshaydeo force-pushed the 09-27-adds_delete_option_for_custom_providers branch from c79c40c to f21909b Compare September 28, 2025 12:19
@akshaydeo
akshaydeo force-pushed the 09-28-fixes_costing_and_token_counts_for_streaming_requests branch from af2710e to f880604 Compare September 28, 2025 12:19

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f21909b and f880604.

📒 Files selected for processing (3)
  • core/providers/openai.go (1 hunks)
  • tests/core-providers/openrouter_test.go (1 hunks)
  • tests/core-providers/scenarios/chat_completion_stream.go (7 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
tests/core-providers/openrouter_test.go (3)
tests/core-providers/config/setup.go (1)
  • SetupTest (51-60)
tests/core-providers/config/account.go (2)
  • ComprehensiveTestConfig (42-53)
  • TestScenarios (20-39)
core/schemas/bifrost.go (1)
  • OpenRouter (54-54)
tests/core-providers/scenarios/chat_completion_stream.go (1)
core/schemas/bifrost.go (2)
  • BifrostResponse (515-528)
  • BifrostStream (827-830)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
tests/core-providers/openrouter_test.go (1)

44-110: Stabilize new OpenRouter Anthropic/Llama suites to reduce CI flake.

These add real E2E paths against specific models. To keep CI stable across rate limits/model availability, consider gating with an env/flag (e.g., RUN_OPENROUTER_E2E=1) or honoring SkipReason when credentials/quotas aren’t present. Optionally add t.Parallel() only where rate limits permit.

If desired, I can add a small helper that checks for credentials/quotas and calls t.Skipf with SkipReason when unavailable.

tests/core-providers/scenarios/chat_completion_stream.go (1)

49-49: Make usage assertions tolerant and tied to the final metadata chunk.

Some providers/proxies only emit usage in the final metadata chunk (choices=[]), while others may include zero/placeholder usage in interim chunks. Restrict per-chunk validations to metadata-only chunks to avoid false failures; keep stronger checks on the last chunk.

Apply diffs to guard by len(response.Choices) == 0:

- if response.Usage != nil {
+ if response.Usage != nil && len(response.Choices) == 0 {
   hasReceivedUsage = true
   ...
 }

and in the tool-call stream:

- if response.Usage != nil {
+ if response.Usage != nil && len(response.Choices) == 0 {
   hasReceivedUsageWithTools = true
   ...
 }

This preserves the stronger final-usage checks below while avoiding brittle assumptions mid‑stream. Based on docs. (community.openai.com)

Also applies to: 101-115, 130-148, 155-160, 217-219, 236-250, 285-292

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f21909b and f880604.

📒 Files selected for processing (3)
  • core/providers/openai.go (1 hunks)
  • tests/core-providers/openrouter_test.go (1 hunks)
  • tests/core-providers/scenarios/chat_completion_stream.go (7 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
tests/core-providers/openrouter_test.go (3)
tests/core-providers/config/setup.go (1)
  • SetupTest (51-60)
tests/core-providers/config/account.go (2)
  • ComprehensiveTestConfig (42-53)
  • TestScenarios (20-39)
core/schemas/bifrost.go (1)
  • OpenRouter (54-54)
tests/core-providers/scenarios/chat_completion_stream.go (1)
core/schemas/bifrost.go (2)
  • BifrostResponse (515-528)
  • BifrostStream (827-830)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
🔇 Additional comments (1)
core/providers/openai.go (1)

502-515: Refactor usage accumulator and expand scanner buffer

  • Change the accumulator declaration before the stream loop from
    usage := &schemas.LLMUsage{}
    to
    var usage *schemas.LLMUsage
  • Replace the in-chunk summing logic with a nil-check + latest-first (fallback to deltas) block:
    -            if usage != nil {
    -                usage.PromptTokens += response.Usage.PromptTokens
    -                usage.CompletionTokens += response.Usage.CompletionTokens
    -                usage.TotalTokens += response.Usage.TotalTokens
    -            } else {
    -                usage = response.Usage
    -            }
    +            if usage == nil {
    +                usage = &schemas.LLMUsage{}
    +            }
    +            // Use the highest TotalTokens seen to avoid double-counting; sum only if deltas
    +            if response.Usage.TotalTokens >= usage.TotalTokens {
    +                *usage = *response.Usage
    +            } else {
    +                usage.PromptTokens += response.Usage.PromptTokens
    +                usage.CompletionTokens += response.Usage.CompletionTokens
    +                usage.TotalTokens += response.Usage.TotalTokens
    +            }
    +            response.Usage = nil
  • Immediately after
    scanner := bufio.NewScanner(resp.Body)
    add
    scanner.Buffer(make([]byte, 0, 64*1024), 2*1024*1024)
  • Manually verify the provider’s streaming behavior (OpenAI vs. proxies) to confirm whether usage only appears on the final chunk (so “latest” is sufficient) or if you must sum deltas.

@akshaydeo
akshaydeo force-pushed the 09-28-fixes_costing_and_token_counts_for_streaming_requests branch 2 times, most recently from 8aa3421 to 598ed26 Compare September 29, 2025 09:58
@akshaydeo
akshaydeo force-pushed the 09-28-fixes_costing_and_token_counts_for_streaming_requests branch from 598ed26 to 62870f9 Compare September 29, 2025 10:27
@coderabbitai
coderabbitai Bot requested a review from danpiths September 29, 2025 10:29

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
framework/logstore/tables.go (1)

235-242: Guard against nil inner error before clearing it

l.ErrorDetailsParsed.Error can legitimately be nil (e.g., when upstream error metadata was absent), so dereferencing it here will panic and break request logging. Please guard the assignment so we only clear the nested error when the parent struct exists.

 	if l.ErrorDetailsParsed != nil {
-		l.ErrorDetailsParsed.Error.Error = nil
+		if l.ErrorDetailsParsed.Error != nil {
+			l.ErrorDetailsParsed.Error.Error = nil
+		}
 		if data, err := json.Marshal(l.ErrorDetailsParsed); err != nil {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f880604 and 62870f9.

📒 Files selected for processing (30)
  • core/bifrost.go (1 hunks)
  • core/changelog.md (1 hunks)
  • core/providers/openai.go (1 hunks)
  • core/version (1 hunks)
  • framework/changelog.md (1 hunks)
  • framework/logstore/sqlite.go (1 hunks)
  • framework/logstore/tables.go (1 hunks)
  • framework/version (1 hunks)
  • plugins/governance/changelog.md (1 hunks)
  • plugins/governance/version (1 hunks)
  • plugins/jsonparser/changelog.md (1 hunks)
  • plugins/jsonparser/version (1 hunks)
  • plugins/logging/changelog.md (1 hunks)
  • plugins/logging/main.go (1 hunks)
  • plugins/logging/operations.go (4 hunks)
  • plugins/logging/streaming.go (6 hunks)
  • plugins/maxim/changelog.md (1 hunks)
  • plugins/maxim/version (1 hunks)
  • plugins/mocker/changelog.md (1 hunks)
  • plugins/mocker/version (1 hunks)
  • plugins/semanticcache/changelog.md (1 hunks)
  • plugins/semanticcache/version (1 hunks)
  • plugins/telemetry/changelog.md (1 hunks)
  • plugins/telemetry/version (1 hunks)
  • tests/core-providers/openrouter_test.go (1 hunks)
  • tests/core-providers/scenarios/chat_completion_stream.go (7 hunks)
  • transports/bifrost-http/handlers/logging.go (1 hunks)
  • transports/changelog.md (1 hunks)
  • transports/version (1 hunks)
  • ui/app/logs/views/logDetailsSheet.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (16)
  • plugins/maxim/version
  • core/changelog.md
  • framework/version
  • plugins/semanticcache/version
  • framework/logstore/sqlite.go
  • core/version
  • plugins/logging/main.go
  • framework/changelog.md
  • transports/version
  • plugins/mocker/changelog.md
  • plugins/logging/changelog.md
  • plugins/jsonparser/version
  • plugins/mocker/version
  • plugins/semanticcache/changelog.md
  • plugins/jsonparser/changelog.md
  • transports/bifrost-http/handlers/logging.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • core/providers/openai.go
  • tests/core-providers/openrouter_test.go
🧰 Additional context used
🧬 Code graph analysis (4)
plugins/logging/operations.go (2)
plugins/logging/main.go (2)
  • LoggerPlugin (117-132)
  • CreatedTimestampKey (39-39)
framework/logstore/tables.go (2)
  • Log (70-116)
  • Log (119-121)
tests/core-providers/scenarios/chat_completion_stream.go (1)
core/schemas/bifrost.go (2)
  • BifrostResponse (515-528)
  • BifrostStream (827-830)
core/bifrost.go (1)
core/schemas/bifrost.go (1)
  • BifrostContextKeyStreamEndIndicator (104-104)
plugins/logging/streaming.go (2)
plugins/logging/main.go (1)
  • LoggerPlugin (117-132)
core/schemas/bifrost.go (1)
  • BifrostError (838-847)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
🔇 Additional comments (11)
plugins/governance/changelog.md (1)

4-5: Changelog update looks good. Entries follow the established format and clearly capture the two version bumps.

plugins/logging/operations.go (4)

40-40: LGTM! Context propagation improvement.

The function call correctly uses the new signature with context as the first parameter, enabling better context-aware latency calculations.


145-145: LGTM! Consistent context propagation.

The error handling path correctly uses the updated function signature with context as the first parameter.


185-185: LGTM! Context propagation maintained.

The final chunk processing correctly uses the updated function signature with context as the first parameter.


270-285: Approve calculateLatency fallback and retry logic.
The retryOnNotFound implementation in plugins/logging/main.go correctly retries on logstore.ErrNotFound up to three times with 1s delays and respects context cancellation, so the fallback in calculateLatency is safe as implemented.

plugins/logging/streaming.go (6)

9-9: LGTM! Appropriate JSON library choice.

Adding sonic for JSON marshaling is a good choice for performance-critical serialization operations.


129-129: LGTM! Enhanced function signature for better error handling.

The addition of context and error parameters enables proper context propagation and streaming error handling in accumulated chunks processing.


142-142: LGTM! Consistent context propagation.

The calculateLatency call correctly uses the updated signature with context as the first parameter, maintaining consistency across the codebase.


151-153: LGTM! Proper error status handling.

The conditional logic correctly sets the status to "error" when a response error is provided, ensuring accurate logging of streaming response states.


168-173: LGTM! Proper error vs success case handling.

The conditional logic correctly separates error serialization from normal output message handling. The use of sonic.Marshal for error serialization is appropriate.

Consider handling the sonic.Marshal error explicitly, though the current implementation using _ is acceptable for this use case.


412-412: LGTM! Call site properly updated.

The function call correctly uses the new signature, properly dereferencing the context and passing the error parameter for comprehensive streaming error handling.

Comment thread core/bifrost.go Outdated
@akshaydeo
akshaydeo force-pushed the 09-28-fixes_costing_and_token_counts_for_streaming_requests branch from 62870f9 to 568f1bb Compare September 29, 2025 11:02

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
plugins/logging/operations.go (1)

40-45: Don’t fail the whole update on latency lookup errors.

updateLogEntry currently returns on calculateLatency error, unlike the streaming path which degrades gracefully. Prefer logging a warning and proceeding without latency to avoid dropping updates when created_at lookup transiently fails.

-        latency, err := p.calculateLatency(ctx, requestID, timestamp)
-        if err != nil {
-            return err
-        }
-        updates["latency"] = latency
+        if latency, err := p.calculateLatency(ctx, requestID, timestamp); err == nil {
+            updates["latency"] = latency
+        } else {
+            p.logger.Warn("calculateLatency failed for %s: %v", requestID, err)
+        }
🧹 Nitpick comments (4)
plugins/logging/operations.go (2)

185-190: Final-chunk latency: degrade gracefully instead of erroring.

If created_at fetch fails here, the entire final update is aborted. Log and continue; omit latency rather than failing the write.

-        latency, err = p.calculateLatency(ctx, requestID, timestamp)
-        if err != nil {
-            return fmt.Errorf("failed to get created_at for latency calculation: %w", err)
-        }
-        needsLatency = true
+        if l, err := p.calculateLatency(ctx, requestID, timestamp); err == nil {
+            latency = l
+            needsLatency = true
+        } else {
+            p.logger.Warn("calculateLatency failed for %s: %v", requestID, err)
+        }

270-285: Clamp negative latency to 0 to handle clock skew.

If currentTime < created_at (clock drift), latency becomes negative. Clamp to 0ms.

-    if ctxTimestamp, ok := ctx.Value(CreatedTimestampKey).(time.Time); ok {
-        return float64(currentTime.Sub(ctxTimestamp).Nanoseconds()) / 1e6, nil
-    }
+    if ctxTimestamp, ok := ctx.Value(CreatedTimestampKey).(time.Time); ok {
+        d := currentTime.Sub(ctxTimestamp)
+        if d < 0 {
+            d = 0
+        }
+        return float64(d.Nanoseconds()) / 1e6, nil
+    }
@@
-    return float64(currentTime.Sub(originalEntry.CreatedAt).Nanoseconds()) / 1e6, nil
+    d := currentTime.Sub(originalEntry.CreatedAt)
+    if d < 0 {
+        d = 0
+    }
+    return float64(d.Nanoseconds()) / 1e6, nil
plugins/logging/streaming.go (2)

141-146: Guard latency calc when FinalTimestamp is zero.

If FinalTimestamp wasn’t set, latency uses zero time. Default to now.

-    latency, err := p.calculateLatency(ctx, requestID, accumulator.FinalTimestamp)
+    ts := accumulator.FinalTimestamp
+    if ts.IsZero() {
+        ts = time.Now()
+    }
+    latency, err := p.calculateLatency(ctx, requestID, ts)

129-137: Defer order is subtle; add intent comment.

cleanupStreamAccumulator is deferred after Unlock defer, so it executes first (LIFO) while the mutex is still held. It’s correct but non‑obvious—add a comment to prevent accidental reordering.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 62870f9 and 568f1bb.

📒 Files selected for processing (30)
  • core/bifrost.go (1 hunks)
  • core/changelog.md (1 hunks)
  • core/providers/openai.go (1 hunks)
  • core/version (1 hunks)
  • framework/changelog.md (1 hunks)
  • framework/logstore/sqlite.go (1 hunks)
  • framework/logstore/tables.go (1 hunks)
  • framework/version (1 hunks)
  • plugins/governance/changelog.md (1 hunks)
  • plugins/governance/version (1 hunks)
  • plugins/jsonparser/changelog.md (1 hunks)
  • plugins/jsonparser/version (1 hunks)
  • plugins/logging/changelog.md (1 hunks)
  • plugins/logging/main.go (1 hunks)
  • plugins/logging/operations.go (4 hunks)
  • plugins/logging/streaming.go (6 hunks)
  • plugins/maxim/changelog.md (1 hunks)
  • plugins/maxim/version (1 hunks)
  • plugins/mocker/changelog.md (1 hunks)
  • plugins/mocker/version (1 hunks)
  • plugins/semanticcache/changelog.md (1 hunks)
  • plugins/semanticcache/version (1 hunks)
  • plugins/telemetry/changelog.md (1 hunks)
  • plugins/telemetry/version (1 hunks)
  • tests/core-providers/openrouter_test.go (1 hunks)
  • tests/core-providers/scenarios/chat_completion_stream.go (7 hunks)
  • transports/bifrost-http/handlers/logging.go (1 hunks)
  • transports/changelog.md (1 hunks)
  • transports/version (1 hunks)
  • ui/app/logs/views/logDetailsSheet.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (4)
  • plugins/governance/version
  • framework/logstore/sqlite.go
  • plugins/logging/main.go
  • plugins/semanticcache/version
🚧 Files skipped from review as they are similar to previous changes (13)
  • tests/core-providers/openrouter_test.go
  • plugins/maxim/version
  • tests/core-providers/scenarios/chat_completion_stream.go
  • framework/logstore/tables.go
  • plugins/semanticcache/changelog.md
  • framework/changelog.md
  • plugins/telemetry/version
  • transports/bifrost-http/handlers/logging.go
  • ui/app/logs/views/logDetailsSheet.tsx
  • transports/version
  • framework/version
  • plugins/telemetry/changelog.md
  • transports/changelog.md
🧰 Additional context used
🧬 Code graph analysis (3)
plugins/logging/streaming.go (2)
plugins/logging/main.go (1)
  • LoggerPlugin (117-132)
core/schemas/bifrost.go (1)
  • BifrostError (838-847)
plugins/logging/operations.go (2)
plugins/logging/main.go (2)
  • LoggerPlugin (117-132)
  • CreatedTimestampKey (39-39)
framework/logstore/tables.go (2)
  • Log (70-116)
  • Log (119-121)
core/bifrost.go (1)
core/schemas/bifrost.go (1)
  • BifrostContextKeyStreamEndIndicator (104-104)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
  • GitHub Check: Graphite / mergeability_check
🔇 Additional comments (7)
plugins/governance/changelog.md (1)

4-5: Changelog entries aligned with version bumps.

Documenting the core 1.1.38 and framework 1.0.24 upgrades here keeps governance release notes in sync with the rest of the stack.

plugins/logging/changelog.md (1)

4-6: New changelog entries capture the logging fix.

Noting the streaming logging fix alongside the coordinated core/framework bumps gives downstream consumers clear release context.

plugins/maxim/changelog.md (1)

4-5: Maxim changelog stays consistent with global upgrades.

Listing both core and framework version bumps keeps this plugin’s release notes aligned with the wider rollout.

plugins/mocker/version (1)

1-1: Plugin version bump looks consistent.

The 1.2.15 bump matches the coordinated plugin release cadence reflected elsewhere in the stack.

core/bifrost.go (1)

1138-1149: Thanks for restoring post-hook recovery handling.

This mirrors the non-stream path: we now respect post-hook overrides (both recovered errors and synthetic responses) while still marking the stream end and releasing the channel. Looks solid.

plugins/logging/streaming.go (2)

412-413: LGTM on context/error propagation and single-run gating.

processAccumulatedChunks now receives ctx and respErr, and IsComplete prevents double processing. Looks good.

If you can, run the OpenRouter streaming tests to ensure error-finalization still fires the callback once.


58-66: No nil‐check needed for Function—FunctionCall is a non‐pointer struct
The Function field on ToolCall is declared as a FunctionCall (not *FunctionCall), so it can never be nil and does not require a guard.

Likely an incorrect or invalid review comment.

Comment thread core/providers/openai.go
Comment thread plugins/logging/operations.go
Comment thread plugins/logging/streaming.go
@akshaydeo
akshaydeo force-pushed the 09-28-fixes_costing_and_token_counts_for_streaming_requests branch from 568f1bb to 7496a33 Compare September 29, 2025 11:34

akshaydeo commented Sep 29, 2025

Copy link
Copy Markdown
Contributor Author

Merge activity

  • Sep 29, 11:55 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Sep 29, 11:57 AM UTC: Graphite rebased this pull request as part of a merge.
  • Sep 29, 11:57 AM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo
akshaydeo changed the base branch from 09-27-adds_delete_option_for_custom_providers to graphite-base/528 September 29, 2025 11:55
@akshaydeo
akshaydeo changed the base branch from graphite-base/528 to main September 29, 2025 11:55
@akshaydeo
akshaydeo force-pushed the 09-28-fixes_costing_and_token_counts_for_streaming_requests branch from 7496a33 to 44990dc Compare September 29, 2025 11:56
@akshaydeo
akshaydeo merged commit f87886d into main Sep 29, 2025
3 of 4 checks passed
@akshaydeo
akshaydeo deleted the 09-28-fixes_costing_and_token_counts_for_streaming_requests branch September 29, 2025 11:57
akshaydeo added a commit that referenced this pull request Nov 17, 2025
## Summary

Improves token usage tracking in OpenAI streaming responses and expands OpenRouter test coverage with additional model tests.

## Changes

- Fixed token usage calculation in OpenAI streaming responses by properly accumulating usage data when it arrives in multiple chunks
- Enhanced streaming tests to validate token usage information throughout the stream and in final responses
- Added comprehensive tests for Anthropic Claude and Meta Llama models via OpenRouter
- Removed the requirement for an OpenRouter API key in tests to allow CI to run these tests

## Type of change

- [x] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [x] Core (Go)
- [ ] Transports (HTTP)
- [x] Providers/Integrations
- [ ] Plugins
- [ ] UI (Next.js)
- [ ] Docs

## How to test

Run the OpenRouter tests to verify proper token usage tracking and model support:

```sh
# Run all OpenRouter tests
go test -v ./tests/core-providers -run TestOpenRouter

# Run specific model tests
go test -v ./tests/core-providers -run TestOpenRouterAnthropic
go test -v ./tests/core-providers -run TestOpenRouterMetaLlama
```

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

Fixes issues with token usage tracking in streaming responses where usage information was being overwritten instead of accumulated.

## Security considerations

No security implications.

## Checklist

- [x] I added/updated tests where appropriate
- [x] I verified builds succeed (Go and UI)
- [x] I verified the CI pipeline passes locally if applicable
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