Skip to content

fixed seed placements - #4049

Merged
akshaydeo merged 2 commits into
v2.0.0from
06-04-fixed_seed_placements
Jun 17, 2026
Merged

fixed seed placements#4049
akshaydeo merged 2 commits into
v2.0.0from
06-04-fixed_seed_placements

Conversation

@akshaydeo

@akshaydeo akshaydeo commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Briefly explain the purpose of this PR and the problem it solves.

Changes

  • What was changed and why
  • Any notable design decisions or trade-offs

Type of change

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

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

Describe the steps to validate this change. Include commands and expected outcomes.

# Core/Transports
go version
go test ./...

# UI
cd ui
pnpm i || npm i
pnpm test || npm test
pnpm build || npm run build

If adding new configs or environment variables, document them here.

Screenshots/Recordings

If UI changes, add before/after screenshots or short clips.

Breaking changes

  • Yes
  • No

If yes, describe impact and migration instructions.

Related issues

Link related issues and discussions. Example: Closes #123

Security considerations

Note any security implications (auth, secrets, PII, sandboxing, etc.).

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

Summary by CodeRabbit

  • New Features

    • Added an agent handover page that displays browser sign-in completion status with contextual messaging and visual indicators.
  • Chores

    • Updated end-to-end seeding CLI/tooling and module configuration (internal).
    • Added a development-mode proxy for the dashboard to improve local UI development workflows.

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Extracts e2e seeding into a standalone cmd/e2eseed Go module and rewires entrypoints/tests to use the seed package, replaces bifrost.Ptr calls with new() in governance virtual-key extraction, adds a dashboard dev-mode proxy to the Vite dev server, and introduces an agent handover route and UI component.

Changes

E2E Seed Module Reorganization

Layer / File(s) Summary
Module initialization and dependency pinning
cmd/e2eseed/go.mod
Module path set to github.com/maximhq/bifrost/cmd/e2eseed with Go 1.26.3; direct dependencies on core, framework, and GORM (PostgreSQL/SQLite drivers); indirect dependencies pinned.
Main entrypoint and seed package rename
cmd/e2eseed/main.go, cmd/e2eseed/seed/seed.go
Adds CLI run() wiring to call seed.DefaultOptions, flag parsing, seed.NormalizeOptions, seed.InitEncryption, seed.OpenDB for config/logs, seed.SeedBase, optional summary write; package renamed to seed.
Test command rewiring to seed package
tests/cmd/e2eseed/main.go
Test main switched to import/use tests/cmd/seed helpers (DefaultOptions, NormalizeOptions, InitEncryption, OpenDB, SeedBase, WriteJSONFile) with DB open error wrapping.

Governance Virtual Key HTTP Extraction

Layer / File(s) Summary
Virtual key pointer construction refactor
plugins/governance/utils.go
parseVirtualKeyFromHTTPRequest now constructs returned *string values with new(...) instead of bifrost.Ptr(...) for x-bf-vk, Authorization Bearer token, x-api-key, and x-goog-api-key code paths.

Dashboard Dev Proxy and Agent Handover UI

Layer / File(s) Summary
Dashboard development mode proxy
transports/bifrost-http/handlers/ui.go
Adds uiDevServerAddr and shared fasthttp.HostClient; serveDashboard delegates to serveDevDashboard in dev mode which rewrites request host/scheme/Host header, forwards to Vite dev server, and copies the response.
Agent handover route and UI component
ui/app/_fallbacks/enterprise/components/agent/handoverView.tsx, ui/app/agent/handover/layout.tsx, ui/app/agent/handover/page.tsx
Adds AgentHandoverView component that reads status query, derives isComplete, and renders success/error messaging; wires /agent/handover route and page to render the component.

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly Related PRs

  • maximhq/bifrost#4098: Similar seed-command structural wiring and test entrypoint updates related to the e2eseed/seed refactor.

Suggested Reviewers

  • Pratham-Mishra04
  • danpiths

Poem

🐰 A tiny seed in a new module bed,
Pointers hop home where new() gently led,
Dev proxy hums to Vite's sunny tune,
Agents land safe beneath the handover moon,
Happy bytes and carrots for the crew!

🚥 Pre-merge checks | ✅ 1 | ❌ 4

❌ Failed checks (3 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is entirely a blank template with no actual content filled in. All sections (Summary, Changes, Type of change, Affected areas, etc.) lack substantive information. Complete all required sections with specific details about the changes, affected areas, testing approach, and any breaking changes or security considerations.
Linked Issues check ⚠️ Warning The changes do not relate to the linked issue #123 (Files API Support). The PR implements e2eseed module reorganization and agent handover UI routes, which are unrelated to file API functionality for providers like OpenAI or Anthropic.
Out of Scope Changes check ⚠️ Warning Changes include agent handover UI routes and modifications to plugins/governance/utils.go that are not mentioned in the linked issue objectives. The PR scope appears misaligned with issue #123 requirements.
Title check ❓ Inconclusive The title 'fixed seed placements' is vague and does not clearly convey the specific nature of the changes. It lacks descriptive detail about what 'seed placements' refers to. Provide a more descriptive title that clearly indicates the main objective, such as 'Reorganize e2eseed module structure and add agent handover routes' or 'Refactor seed module package organization'.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 06-04-fixed_seed_placements

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

@akshaydeo
akshaydeo marked this pull request as ready for review June 4, 2026 09:24
@CLAassistant

CLAassistant commented Jun 4, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

akshaydeo commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

@greptile-apps

greptile-apps Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

Safe to merge; all changes are additive tooling, a dev-only proxy, and a new UI route with no impact on production request paths.

The governance plugin change is a no-op behavioural difference (Go 1.26 new(expr) is equivalent to the previous bifrost.Ptr). The UIHandler dev proxy is correctly guarded behind IsDevMode() and attached as a struct field rather than a global. The agent handover page is an isolated new route. The only concern is the duplicated seed.go between cmd/e2eseed/ and tests/cmd/, which is a maintenance concern but does not affect runtime correctness.

cmd/e2eseed/seed/seed.go and tests/cmd/seed/seed.go are exact duplicates; any future logic change must be applied to both files.

Important Files Changed

Filename Overview
cmd/e2eseed/go.mod New standalone module for the OSS e2e seeder, pinning released versions of core and framework; correctly scoped as a standalone tool module.
cmd/e2eseed/main.go New entry-point for the OSS seeder; identical logic to tests/cmd/e2eseed/main.go, standard flag-parsing pattern, correct error propagation.
cmd/e2eseed/seed/seed.go Exact copy of tests/cmd/seed/seed.go; logic is sound but duplication creates future maintenance risk if the two implementations diverge.
tests/cmd/seed/seed.go Unchanged seeder implementation in the tests module; content is identical to the new cmd/e2eseed/seed/seed.go.
transports/bifrost-http/handlers/ui.go Adds a dev-mode Vite proxy attached as a nullable struct field on UIHandler; correctly replaces the previously package-level global with DI-friendly field, adds timeout guards, and falls back to embedded UI on error.
plugins/governance/utils.go Uses new(variable) syntax valid in Go 1.26 to create string pointers; no behavioral change from the original bifrost.Ptr usage.
ui/app/_fallbacks/enterprise/components/agent/AgentHandoverView.tsx New OSS fallback component for the agent browser sign-in handover page; reads ?status query param to toggle completion message and icon.
ui/app/agent/handover/layout.tsx Registers the /agent/handover TanStack Router route using createFileRoute; straightforward route declaration.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Incoming HTTP request] --> B{IsDevMode?}
    B -- No --> E[serveDashboard: embedded FS]
    B -- Yes --> C{uiDevClient != nil?}
    C -- No --> E
    C -- Yes --> D[serveDevDashboard: proxy to Vite :3000]
    D -- success --> F[Copy resp to ctx.Response]
    D -- error / timeout --> E
    E --> G[Serve embedded UI asset or SPA fallback]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[Incoming HTTP request] --> B{IsDevMode?}
    B -- No --> E[serveDashboard: embedded FS]
    B -- Yes --> C{uiDevClient != nil?}
    C -- No --> E
    C -- Yes --> D[serveDevDashboard: proxy to Vite :3000]
    D -- success --> F[Copy resp to ctx.Response]
    D -- error / timeout --> E
    E --> G[Serve embedded UI asset or SPA fallback]
Loading

Reviews (13): Last reviewed commit: "fixed seed placements" | Re-trigger Greptile

Comment thread plugins/governance/utils.go
Comment thread transports/bifrost-http/handlers/ui.go Outdated

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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/e2eseed/seed/seed.go`:
- Around line 1-2: Update the top-of-file package comment to match the declared
package name by changing the package docstring from "Package e2eseed ..." to
"Package seed ..." so the package comment and the declaration (package seed) are
consistent; edit the file-level comment at the top of seed.go where the current
package comment appears to reflect the new package name.

In `@plugins/governance/store.go`:
- Around line 27-29: The code updates gs.virtualKeys in many VK rewrite paths
but doesn't update gs.virtualKeysByID, causing GetVirtualKeyByID to become
stale; fix by centralizing VK writes through the existing storeVirtualKey(...)
helper (which should atomically write both gs.virtualKeys and
gs.virtualKeysByID) and replace all direct writes to gs.virtualKeys in rewrite
sites (e.g., team/customer unlink handlers, budget/rate-limit reference refresh
paths, and the locations mentioned in the review) with calls to
storeVirtualKey(VK) so both maps stay synchronized and race-safe for
GetVirtualKey and GetVirtualKeyByID lookups.

In `@transports/bifrost-http/handlers/ui.go`:
- Around line 155-157: The handler currently swallows errors from
uiDevClient.Do(&req, &resp) and silently falls back to embedded files; update
the error path to log the proxy error before returning false. Locate the call to
uiDevClient.Do in the UI request handler and add a log statement that includes
the error (and context like "Dev server proxy failed, falling back to embedded
UI"), using the existing logger in the handler context if available (or the
package logger) so developers can see why the dev-mode proxy failed; keep the
existing return false behavior after logging.
- Around line 16-18: The uiDevClient HostClient is created without timeouts
causing potential indefinite hangs; update the uiDevClient initialization (the
variable uiDevClient that uses uiDevServerAddr) to set ReadTimeout and
WriteTimeout (and optionally IdleTimeout/MaxIdleConnDuration) to reasonable
values (e.g., a few seconds) and add the time import to the file so the
durations compile; ensure the updated HostClient literal includes those timeout
fields to avoid blocking on OS-level TCP timeouts.

In `@ui/app/_fallbacks/enterprise/components/agent/handoverView.tsx`:
- Around line 1-22: The file is named handoverView.tsx but exports a PascalCase
React component AgentHandoverView; rename the file from handoverView.tsx to
AgentHandoverView.tsx and update any imports that reference the old filename to
import AgentHandoverView (preserving the exported component name) so the
filename matches the component (look for usages/imports of AgentHandoverView or
handoverView and update them accordingly).
- Around line 5-6: The component currently memoizes status via useMemo(() => new
URLSearchParams(window.location.search).get("status"), []) which never updates;
remove useMemo and derive status on each render (e.g., const status = new
URLSearchParams(window.location.search).get("status") or read from the router's
search params) so status and the dependent isComplete (const isComplete =
!status || status === "complete") update when the URL changes; update any tests
or usages expecting memoization accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: bbc693b0-795e-4702-b883-f9700367d8e4

📥 Commits

Reviewing files that changed from the base of the PR and between 6711ce3 and 035662d.

⛔ Files ignored due to path filters (1)
  • cmd/e2eseed/go.sum is excluded by !**/*.sum
📒 Files selected for processing (10)
  • cmd/e2eseed/go.mod
  • cmd/e2eseed/main.go
  • cmd/e2eseed/seed/seed.go
  • plugins/governance/store.go
  • plugins/governance/store_test.go
  • plugins/governance/utils.go
  • transports/bifrost-http/handlers/ui.go
  • ui/app/_fallbacks/enterprise/components/agent/handoverView.tsx
  • ui/app/agent/handover/layout.tsx
  • ui/app/agent/handover/page.tsx

Comment thread cmd/e2eseed/seed/seed.go Outdated
Comment thread plugins/governance/store.go Outdated
Comment thread transports/bifrost-http/handlers/ui.go Outdated
Comment thread transports/bifrost-http/handlers/ui.go Outdated
Comment thread ui/app/_fallbacks/enterprise/components/agent/AgentHandoverView.tsx
Comment thread ui/app/_fallbacks/enterprise/components/agent/AgentHandoverView.tsx Outdated
@akshaydeo
akshaydeo requested a review from a team as a code owner June 4, 2026 10:02
@akshaydeo
akshaydeo force-pushed the 06-04-fixed_seed_placements branch from 035662d to b39bfd3 Compare June 4, 2026 15:34
@akshaydeo akshaydeo mentioned this pull request Jun 4, 2026
18 tasks

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

Caution

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

⚠️ Outside diff range comments (4)
core/providers/utils/dialer_test.go (1)

295-392: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add coverage for the two untested branches of the new dialer contract.

These tests cover the nil-Dial path and proxy bypass, but not allowPrivateNetwork=true or a client with DialTimeout set. Both are easy regression points for the new signature, and the latter follows different logic from the path under test today.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@core/providers/utils/dialer_test.go` around lines 295 - 392, Add two new
tests to cover the missing dialer branches: one that calls
ConfigureDialer(client, true) (allowPrivateNetwork=true) and asserts that
dialing a private IP (e.g., "10.0.0.1:80") is allowed (no "private IP" SSRF
error) and follows normal Dial behavior, and another that constructs a client
with DialTimeout set (e.g., client.DialTimeout > 0), calls
ConfigureDialer(client, false) and verifies the path that uses timeouts (e.g.,
that dialing an unroutable address yields a timeout/dial error rather than the
proxy/no-op branch). Reference ConfigureDialer, the allowPrivateNetwork
parameter, and the client's DialTimeout/Dial field to locate where to add these
tests.
core/providers/utils/utils.go (2)

278-327: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep the IP-class SSRF checks on the DialTimeout path.

This branch dials addr directly. If a caller sets client.DialTimeout to customize connect timeouts without also installing a proxy/custom Dial, the new private/link-local/unspecified IP checks are skipped entirely.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@core/providers/utils/utils.go` around lines 278 - 327, The DialTimeout branch
(case existingDialTimeout != nil) currently dials addr directly and skips the
new SSRF IP-class checks; change it to resolve host -> enforce the same checks
(ip.IsUnspecified, network.IsLinkLocal(ip), and block private IPs unless
ip.IsLoopback() or allowPrivateNetwork) for each resolved IP, and then call
existingDialTimeout using the IP literal + port (preserving client.DialTimeout
semantics) or try next resolved IP on failure; reference existingDialTimeout,
client.DialTimeout, allowPrivateNetwork and reuse the same validation logic and
error messages used in the default branch before dialing.

1090-1117: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Require a full SSE field token before treating the stream as SSE.

peekHasPrefix currently returns true for partial matches. On a chunked first read, a non-SSE body that happens to start with d, e, i, or r is misclassified as SSE and bypasses the non-SSE drain.

🛠️ Proposed fix
func peekHasPrefix(reader *bufio.Reader, prefix []byte) bool {
-	n := min(reader.Buffered(), len(prefix))
-	if n == 0 {
-		return false
-	}
-	peeked, err := reader.Peek(n)
-	return err == nil && bytes.Equal(peeked, prefix[:n])
+	peeked, err := reader.Peek(len(prefix))
+	if err != nil {
+		return false
+	}
+	return bytes.Equal(peeked, prefix)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@core/providers/utils/utils.go` around lines 1090 - 1117, The SSE detection
incorrectly accepts partial token matches because peekHasPrefix uses
min(reader.Buffered(), len(prefix)) and returns true on partial matches; update
peekHasPrefix (used by hasSSEPrefix) to require the full prefix length: if
reader.Buffered() < len(prefix) return false, then call reader.Peek(len(prefix))
and only return true when err==nil and bytes.Equal(peeked, prefix). This ensures
only complete SSE field tokens ("data:", "event:", "id:", "retry:") are treated
as SSE.
core/providers/openai/openai.go (1)

6939-6948: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the OpenAI URL builder for passthrough routes.

Lines 6945 and 7020 still hand-build BaseURL + "/v1" + path. That bypasses the OpenAI-specific path normalization used for ChatGPTOAuth, so passthrough and passthrough streaming can hit the wrong upstream route when OAuth mode is enabled.

♻️ Proposed fix
-	url := provider.networkConfig.BaseURL + "/v1" + path
+	url := provider.buildFullURL("/v1" + path)
 	if req.RawQuery != "" {
 		url += "?" + req.RawQuery
 	}
-	url := provider.networkConfig.BaseURL + "/v1" + path
+	url := provider.buildFullURL("/v1" + path)
 	if req.RawQuery != "" {
 		url += "?" + req.RawQuery
 	}

Based on learnings: In core/providers/openai, when ChatGPTOAuth is enabled, Passthrough and PassthroughStream must build "/v1/..." routes through OpenAIProvider.buildRequestURL(...) or OpenAIProvider.buildFullURL(...) so the /v1 normalization logic runs.

Also applies to: 7016-7023

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@core/providers/openai/openai.go` around lines 6939 - 6948, The code is
manually composing URLs with provider.networkConfig.BaseURL + "/v1" + path which
bypasses OpenAI-specific normalization (breaking ChatGPTOAuth passthrough);
replace these manual concatenations in the passthrough and passthrough-stream
handlers by calling the OpenAI provider URL helpers (e.g.
OpenAIProvider.buildRequestURL(...) or OpenAIProvider.buildFullURL(...)) so the
"/v1" normalization and OAuth path adjustments run; locate usages around where
`path` and `req.RawQuery` are combined and swap them to use
provider.buildRequestURL(path, req.RawQuery) or the appropriate
provider.buildFullURL(req) method on the OpenAIProvider instance.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@core/providers/openai/openai.go`:
- Around line 6939-6948: The code is manually composing URLs with
provider.networkConfig.BaseURL + "/v1" + path which bypasses OpenAI-specific
normalization (breaking ChatGPTOAuth passthrough); replace these manual
concatenations in the passthrough and passthrough-stream handlers by calling the
OpenAI provider URL helpers (e.g. OpenAIProvider.buildRequestURL(...) or
OpenAIProvider.buildFullURL(...)) so the "/v1" normalization and OAuth path
adjustments run; locate usages around where `path` and `req.RawQuery` are
combined and swap them to use provider.buildRequestURL(path, req.RawQuery) or
the appropriate provider.buildFullURL(req) method on the OpenAIProvider
instance.

In `@core/providers/utils/dialer_test.go`:
- Around line 295-392: Add two new tests to cover the missing dialer branches:
one that calls ConfigureDialer(client, true) (allowPrivateNetwork=true) and
asserts that dialing a private IP (e.g., "10.0.0.1:80") is allowed (no "private
IP" SSRF error) and follows normal Dial behavior, and another that constructs a
client with DialTimeout set (e.g., client.DialTimeout > 0), calls
ConfigureDialer(client, false) and verifies the path that uses timeouts (e.g.,
that dialing an unroutable address yields a timeout/dial error rather than the
proxy/no-op branch). Reference ConfigureDialer, the allowPrivateNetwork
parameter, and the client's DialTimeout/Dial field to locate where to add these
tests.

In `@core/providers/utils/utils.go`:
- Around line 278-327: The DialTimeout branch (case existingDialTimeout != nil)
currently dials addr directly and skips the new SSRF IP-class checks; change it
to resolve host -> enforce the same checks (ip.IsUnspecified,
network.IsLinkLocal(ip), and block private IPs unless ip.IsLoopback() or
allowPrivateNetwork) for each resolved IP, and then call existingDialTimeout
using the IP literal + port (preserving client.DialTimeout semantics) or try
next resolved IP on failure; reference existingDialTimeout, client.DialTimeout,
allowPrivateNetwork and reuse the same validation logic and error messages used
in the default branch before dialing.
- Around line 1090-1117: The SSE detection incorrectly accepts partial token
matches because peekHasPrefix uses min(reader.Buffered(), len(prefix)) and
returns true on partial matches; update peekHasPrefix (used by hasSSEPrefix) to
require the full prefix length: if reader.Buffered() < len(prefix) return false,
then call reader.Peek(len(prefix)) and only return true when err==nil and
bytes.Equal(peeked, prefix). This ensures only complete SSE field tokens
("data:", "event:", "id:", "retry:") are treated as SSE.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a265bb53-a1cd-4ffb-bfcd-98e710bcb38f

📥 Commits

Reviewing files that changed from the base of the PR and between 035662d and b39bfd3.

⛔ Files ignored due to path filters (1)
  • cmd/e2eseed/go.sum is excluded by !**/*.sum
📒 Files selected for processing (23)
  • cmd/e2eseed/go.mod
  • cmd/e2eseed/main.go
  • cmd/e2eseed/seed/seed.go
  • core/providers/anthropic/anthropic.go
  • core/providers/azure/azure.go
  • core/providers/gemini/gemini.go
  • core/providers/gemini/gemini_test.go
  • core/providers/gemini/types.go
  • core/providers/openai/openai.go
  • core/providers/utils/dialer_test.go
  • core/providers/utils/utils.go
  • core/providers/utils/utils_test.go
  • core/providers/vertex/vertex.go
  • framework/modelcatalog/config.go
  • framework/modelcatalog/sync.go
  • plugins/governance/store.go
  • plugins/governance/store_test.go
  • plugins/governance/utils.go
  • tests/e2e/api/collections/provider-harness.json
  • transports/bifrost-http/handlers/ui.go
  • ui/app/_fallbacks/enterprise/components/agent/handoverView.tsx
  • ui/app/agent/handover/layout.tsx
  • ui/app/agent/handover/page.tsx

@akshaydeo
akshaydeo force-pushed the 06-04-fixed_seed_placements branch 2 times, most recently from 1c091f6 to e148b58 Compare June 4, 2026 18:40
@akshaydeo
akshaydeo force-pushed the 06-04-fixed_seed_placements branch from e148b58 to c99bdb2 Compare June 7, 2026 21:24
@akshaydeo akshaydeo mentioned this pull request Jun 8, 2026
18 tasks
@akshaydeo
akshaydeo force-pushed the 06-04-fixed_seed_placements branch 2 times, most recently from 22efdd6 to ed77ca6 Compare June 9, 2026 06:40

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

♻️ Duplicate comments (4)
ui/app/_fallbacks/enterprise/components/agent/handoverView.tsx (2)

1-22: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Rename file to PascalCase to match UI component-file convention.

handoverView.tsx should be PascalCase (for example, AgentHandoverView.tsx) to align with repo UI rules.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/app/_fallbacks/enterprise/components/agent/handoverView.tsx` around lines
1 - 22, Rename the component file from handoverView.tsx to PascalCase
AgentHandoverView.tsx; keep the exported React component name AgentHandoverView
as-is, update all imports/usages that reference the old filename (search for
"handoverView" imports and update them to "AgentHandoverView"), and ensure any
route/fallback registrations or dynamic imports that reference the filename are
updated so the bundler/resolver picks up the renamed file.

Source: Coding guidelines


5-6: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

status becomes stale due to empty-dependency memoization.

With useMemo(..., []), URL search updates on the same mounted route won’t refresh status/isComplete.

Suggested fix
-import { useMemo } from "react";
...
-const status = useMemo(() => new URLSearchParams(window.location.search).get("status"), []);
+const status = new URLSearchParams(window.location.search).get("status");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/app/_fallbacks/enterprise/components/agent/handoverView.tsx` around lines
5 - 6, The current useMemo with an empty dependency causes status/isComplete to
become stale; replace the useMemo-based read of window.location.search with a
reactive search params hook (e.g., useSearchParams from next/navigation) or
otherwise re-evaluate on param change: stop using useMemo(..., []) and instead
call const searchParams = useSearchParams(); const status =
searchParams.get("status"); const isComplete = !status || status === "complete";
(referencing the existing status and isComplete identifiers and removing the
useMemo usage).
transports/bifrost-http/handlers/ui.go (2)

16-19: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add explicit timeouts to uiDevClient to avoid hanging dev requests.

fasthttp.HostClient here has no read/write timeout, so a stalled local dev server can block dashboard requests for a long time.

Suggested fix
+import "time"
 ...
-var uiDevClient = &fasthttp.HostClient{Addr: uiDevServerAddr}
+var uiDevClient = &fasthttp.HostClient{
+	Addr:         uiDevServerAddr,
+	ReadTimeout:  5 * time.Second,
+	WriteTimeout: 5 * time.Second,
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@transports/bifrost-http/handlers/ui.go` around lines 16 - 19, uiDevClient
currently constructs a fasthttp.HostClient with no timeouts, which can hang
requests; update the uiDevClient creation to set sensible timeouts (e.g.,
ReadTimeout and WriteTimeout, and optionally IdleTimeout/MaxConns) on the
fasthttp.HostClient instance that uses uiDevServerAddr so dev-dashboard requests
don’t block indefinitely — locate the uiDevClient variable initialization and
add the timeout fields to that HostClient struct literal.

Source: Coding guidelines


155-157: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Log dev-proxy failures before falling back to embedded UI.

Proxy errors are currently swallowed, which makes local debugging harder when Vite is down or misconfigured.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@transports/bifrost-http/handlers/ui.go` around lines 155 - 157, The call to
uiDevClient.Do(&req, &resp) swallows errors and returns false without logging;
update the error branch so it logs the error (including context like "dev-proxy
request failed") before returning false. Specifically, inside the if err :=
uiDevClient.Do(&req, &resp); err != nil { ... } block, emit a log entry using
the package/service logger available in this handler (e.g., logger, s.logger, or
h.logger) that includes err and relevant request context (req.URL or method) and
then return false.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/e2eseed/seed/seed.go`:
- Line 261: Remove the redundant InitEncryption(opts) call from SeedBase so
encryption initialization is performed by the caller or, alternatively, make
SeedBase responsible and remove the external call; specifically, either delete
the InitEncryption(opts) invocation in SeedBase and rely on the caller's
initialization, or if you prefer SeedBase to own init, document that SeedBase
calls encrypt.Init and remove the caller's InitEncryption usage—refer to the
InitEncryption function and the SeedBase entry point and adjust callers
accordingly to avoid double initialization of encrypt.Init.
- Around line 600-618: Replace usages of the local variable active and
address-taking (&active) in the TableVirtualKey literals with direct calls to
bifrost.Ptr(true); specifically update the IsActive fields in the virtual key
entries (the slice of tables.TableVirtualKey created where IDs like prefix +
"-vk-user-team", "-vk-team-only", "-vk-outside" are defined) to use
bifrost.Ptr(true) instead of &active, and remove the now-unused active := true
declaration.

---

Duplicate comments:
In `@transports/bifrost-http/handlers/ui.go`:
- Around line 16-19: uiDevClient currently constructs a fasthttp.HostClient with
no timeouts, which can hang requests; update the uiDevClient creation to set
sensible timeouts (e.g., ReadTimeout and WriteTimeout, and optionally
IdleTimeout/MaxConns) on the fasthttp.HostClient instance that uses
uiDevServerAddr so dev-dashboard requests don’t block indefinitely — locate the
uiDevClient variable initialization and add the timeout fields to that
HostClient struct literal.
- Around line 155-157: The call to uiDevClient.Do(&req, &resp) swallows errors
and returns false without logging; update the error branch so it logs the error
(including context like "dev-proxy request failed") before returning false.
Specifically, inside the if err := uiDevClient.Do(&req, &resp); err != nil { ...
} block, emit a log entry using the package/service logger available in this
handler (e.g., logger, s.logger, or h.logger) that includes err and relevant
request context (req.URL or method) and then return false.

In `@ui/app/_fallbacks/enterprise/components/agent/handoverView.tsx`:
- Around line 1-22: Rename the component file from handoverView.tsx to
PascalCase AgentHandoverView.tsx; keep the exported React component name
AgentHandoverView as-is, update all imports/usages that reference the old
filename (search for "handoverView" imports and update them to
"AgentHandoverView"), and ensure any route/fallback registrations or dynamic
imports that reference the filename are updated so the bundler/resolver picks up
the renamed file.
- Around line 5-6: The current useMemo with an empty dependency causes
status/isComplete to become stale; replace the useMemo-based read of
window.location.search with a reactive search params hook (e.g., useSearchParams
from next/navigation) or otherwise re-evaluate on param change: stop using
useMemo(..., []) and instead call const searchParams = useSearchParams(); const
status = searchParams.get("status"); const isComplete = !status || status ===
"complete"; (referencing the existing status and isComplete identifiers and
removing the useMemo usage).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1070855e-a1f9-4265-87e1-7f57ee28fe1f

📥 Commits

Reviewing files that changed from the base of the PR and between c99bdb2 and ed77ca6.

⛔ Files ignored due to path filters (1)
  • cmd/e2eseed/go.sum is excluded by !**/*.sum
📒 Files selected for processing (9)
  • cmd/e2eseed/go.mod
  • cmd/e2eseed/main.go
  • cmd/e2eseed/seed/seed.go
  • plugins/governance/utils.go
  • tests/cmd/e2eseed/main.go
  • transports/bifrost-http/handlers/ui.go
  • ui/app/_fallbacks/enterprise/components/agent/handoverView.tsx
  • ui/app/agent/handover/layout.tsx
  • ui/app/agent/handover/page.tsx

Comment thread cmd/e2eseed/seed/seed.go Outdated
Comment thread cmd/e2eseed/seed/seed.go Outdated
@akshaydeo
akshaydeo force-pushed the 06-04-fixed_seed_placements branch from ed77ca6 to 09d6433 Compare June 9, 2026 12:39
This was referenced Jun 9, 2026
@akshaydeo
akshaydeo force-pushed the 06-04-fixed_seed_placements branch from 09d6433 to 6e10d42 Compare June 11, 2026 11:25
Comment thread plugins/governance/utils.go
@akshaydeo
akshaydeo force-pushed the 06-04-fixed_seed_placements branch from 6e10d42 to 0a6211b Compare June 12, 2026 13:31
@akshaydeo
akshaydeo changed the base branch from dev to graphite-base/4049 June 13, 2026 13:17
@akshaydeo
akshaydeo force-pushed the 06-04-fixed_seed_placements branch 2 times, most recently from 60fc782 to a620951 Compare June 13, 2026 13:22
@akshaydeo
akshaydeo changed the base branch from graphite-base/4049 to v2.0.0 June 13, 2026 13:22
@akshaydeo
akshaydeo force-pushed the v2.0.0 branch 2 times, most recently from 1480e3e to 73d20c1 Compare June 16, 2026 17:39
## Summary

Adds Helm chart support for two new Enterprise trace-publishing plugins: **Kafka** and **Google Cloud Pub/Sub**. These plugins allow Bifrost to publish completed traces as JSON messages to a Kafka topic or a GCP Pub/Sub topic respectively.

## Changes

- Added Kafka plugin rendering logic to `_helpers.tpl`, supporting broker addresses, topic, SASL authentication, TLS, compression, batching, and span filtering options.
- Added Pub/Sub plugin rendering logic to `_helpers.tpl`, supporting GCP project/topic IDs, service account key authentication (or ADC), auto topic creation, content logging controls, and span filtering.
- Added JSON schema definitions for both `kafka` and `pubsub` plugin configs in `values.schema.json`, including field-level descriptions, enums, and `anyOf` patterns for env-var-substitutable fields.
- Added conditional schema validation blocks in `transports/config.schema.json` for both plugins, enforcing required fields (`brokers`/`topic` for Kafka; `project_id`/`topic_id` for Pub/Sub).
- Added default-disabled entries for both plugins in `values.yaml` with inline documentation comments covering all supported options.

## Type of change

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

## Affected areas

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

## How to test

Enable the Kafka plugin in your `values.yaml` and confirm the rendered config contains the expected plugin block:

```sh
helm template bifrost ./helm-charts/bifrost \
  --set bifrost.plugins.kafka.enabled=true \
  --set bifrost.plugins.kafka.config.brokers[0]=localhost:9092 \
  --set bifrost.plugins.kafka.config.topic=traces
```

Enable the Pub/Sub plugin and verify the rendered output:

```sh
helm template bifrost ./helm-charts/bifrost \
  --set bifrost.plugins.pubsub.enabled=true \
  --set bifrost.plugins.pubsub.config.project_id=my-project \
  --set bifrost.plugins.pubsub.config.topic_id=my-topic
```

Validate the schema against a config file:

```sh
# Validate transports config schema
npx ajv validate -s transports/config.schema.json -d <your-config.json>
```

**New config fields (Kafka):**

| Field | Description | Default |
|---|---|---|
| `brokers` | Kafka broker addresses | required |
| `topic` | Topic to publish traces to | required |
| `sasl_enabled` | Enable SASL authentication | `false` |
| `tls_enabled` | Enable TLS for broker connections | `false` |
| `compression` | Codec: `none`, `gzip`, `snappy`, `lz4`, `zstd` | `none` |
| `batch_size` | Max messages per batch | `100` |
| `flush_interval_ms` | Max ms before flushing a batch | `1000` |
| `auto_create_topic` | Create topic at startup if missing | `false` |
| `disable_content_logging` | Strip message content from traces | `false` |

**New config fields (Pub/Sub):**

| Field | Description | Default |
|---|---|---|
| `project_id` | GCP project ID | required |
| `topic_id` | Pub/Sub topic ID | required |
| `service_account_key` | SA key JSON or `env.VAR`; omit for ADC | — |
| `auto_create_topic` | Create topic at startup if missing | `false` |
| `disable_content_logging` | Strip content from traces | `false` |

## Breaking changes

- [ ] Yes
- [x] No

## Security considerations

- SASL credentials (`username`, `password`) and the Pub/Sub `service_account_key` support `env.VAR_NAME` substitution to avoid embedding secrets directly in config files.
- TLS CA certificates for Kafka also support env-var substitution.
- Both plugins support `disable_content_logging` to prevent PII or sensitive payload data from being published to the message broker.

## Checklist

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [ ] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [ ] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added Kafka and Pub/Sub as telemetry export backends for distributed tracing.
  * Both plugins are disabled by default and expose configuration for brokers/project/topic, optional auth (SASL/TLS/service account), compression/batching/flush, topic auto-creation, request header capture, and content/span filtering.
  * Chart/values and schema updates add configuration stubs and validation for these plugins.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@akshaydeo
akshaydeo force-pushed the 06-04-fixed_seed_placements branch 2 times, most recently from c7b3186 to 48b7cef Compare June 17, 2026 08:14
@akshaydeo
akshaydeo force-pushed the 06-04-fixed_seed_placements branch from 48b7cef to 39dfc83 Compare June 17, 2026 08:19

akshaydeo commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

Merge activity

  • Jun 17, 2:21 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 17, 2:21 PM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo
akshaydeo merged commit f6af83a into v2.0.0 Jun 17, 2026
9 of 10 checks passed
@akshaydeo
akshaydeo deleted the 06-04-fixed_seed_placements branch June 17, 2026 14:21
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.

Files API Support

3 participants