Skip to content

Conversation

@brendan-kellam
Copy link
Contributor

@brendan-kellam brendan-kellam commented Feb 1, 2026

This PR adds a api_request event that is fired for any api route that uses the apiHandler factory. The event includes a path and source. The source is sourced from the X-Sourcebot-Client-Source header

Summary by CodeRabbit

  • New Features

    • Centralized API handler wrapper that can emit lightweight API-request tracking events.
  • Improvements

    • Requests now include a client-source header for clearer client identification.
    • Removed redundant in-body source fields from search and suggestion requests to streamline payloads.
    • Added a new analytics event for API requests to improve usage insights.

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

@github-actions

This comment has been minimized.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 1, 2026

Warning

Rate limit exceeded

@brendan-kellam has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 16 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.

Walkthrough

Migrates source identification from request bodies to the X-Sourcebot-Client-Source header across clients and routes, and introduces an apiHandler wrapper on many server routes that optionally emits api_request PostHog events.

Changes

Cohort / File(s) Summary
API handler & events
packages/web/src/lib/apiHandler.ts, packages/web/src/lib/posthogEvents.ts
Adds apiHandler wrapper that optionally tracks requests to PostHog and a new api_request event type.
MCP client & schemas
packages/mcp/src/client.ts, packages/mcp/src/schemas.ts, packages/mcp/src/index.ts
Adds X-Sourcebot-Client-Source: mcp header to MCP client requests and removes optional source from MCP search schema/index usage.
Web client headers & schemas
packages/web/src/app/api/(client)/client.ts, packages/web/src/app/[domain]/search/useStreamedSearch.ts, packages/web/src/features/search/types.ts, packages/web/src/app/[domain]/components/searchBar/useSuggestionsData.ts, packages/web/src/features/chat/components/chatBox/useSuggestionsData.ts
Adds X-Sourcebot-Client-Source: sourcebot-web-client header to client calls/streaming; removes source fields from request bodies/schemas.
Server routes (wrapped)
packages/web/src/app/api/(server)/**, packages/web/src/app/api/[domain]/repos/[repoId]/image/route.ts
Replaces many exported route handlers with apiHandler(...) wrapped handlers; several routes now read source from X-Sourcebot-Client-Source header (default 'unknown') and use centralized tracking/error plumbing.
Client-side API calls (web)
packages/web/src/app/api/(client)/client.ts
Adds X-Sourcebot-Client-Source header to multiple client-side API functions (search, getFileSource, listRepos, getVersion, findSearchBasedSymbolReferences/Definitions, getTree, getFiles).

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ServerRoute
  participant apiHandler as apiHandler (wrapper)
  participant PostHog
  Client->>ServerRoute: HTTP request (includes X-Sourcebot-Client-Source)
  ServerRoute->>apiHandler: invoked (wrapper receives req)
  apiHandler-->>PostHog: async emit api_request { path, source } rgba(100,150,250,0.5)
  apiHandler->>ServerRoute: forward to original handler
  ServerRoute-->>Client: HTTP response (JSON / stream / file)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

sourcebot-team

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main objective of adding telemetry/api request tracking across all API routes via the apiHandler wrapper.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% 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
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bkellam/api-events

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/mcp/src/client.ts`:
- Around line 110-133: Resolve the merge conflict markers around the askCodebase
implementation by removing the <<<<<<<, =======, and >>>>>>> lines and keeping
the correct askCodebase function body; ensure the file exports/defines the async
function askCodebase(request: AskCodebaseRequest): Promise<AskCodebaseResponse>
exactly as in the new block and call parseResponse(response,
askCodebaseResponseSchema). Also add or restore the necessary imports for
AskCodebaseRequest, AskCodebaseResponse, askCodebaseResponseSchema (and
parseResponse/env if missing) at the top of the file so the TypeScript compiles
without errors.

In `@packages/web/src/app/api/`(server)/repos/route.ts:
- Around line 1-13: The file contains Git conflict markers and duplicated
imports; remove the conflict markers (<<<<<<<, =======, >>>>>>>) and consolidate
imports into one block so each symbol is imported exactly once — keep required
symbols like apiHandler, buildLinkHeader, listReposQueryParamsSchema,
repositoryQuerySchema, queryParamsSchemaValidationError, serviceErrorResponse,
and isServiceError, and drop unused/old imports such as NextRequest, sew, or
withOptionalAuthV2 if they are not referenced elsewhere in this module; ensure
the final import block imports each identifier only once and re-run lint/type
checks.
🧹 Nitpick comments (1)
packages/web/src/app/[domain]/search/useStreamedSearch.ts (1)

120-125: Extract the source header name/value into a shared constant/helper.

Hard-coded literals here can drift from other API calls; centralizing the header name/value makes future updates safer and more consistent.

♻️ Example refactor
+const SOURCEBOT_CLIENT_SOURCE_HEADER = 'X-Sourcebot-Client-Source';
+const SOURCEBOT_WEB_CLIENT_SOURCE = 'sourcebot-web-client';
+
 // ...
                 const response = await fetch('/api/stream_search', {
                     method: 'POST',
                     headers: {
                         'Content-Type': 'application/json',
-                        'X-Sourcebot-Client-Source': 'sourcebot-web-client',
+                        [SOURCEBOT_CLIENT_SOURCE_HEADER]: SOURCEBOT_WEB_CLIENT_SOURCE,
                     },

@claude
Copy link

claude bot commented Feb 1, 2026

Code review

This PR contains 2 critical issues - unresolved git merge conflicts that will prevent the code from compiling:

Issue 1: Merge conflict in packages/mcp/src/client.ts

Location: Lines 110-133
Link: https://github.com/sourcebot-dev/sourcebot/blob/891737e89ce9ccf251b6397d766687a94678e80c/packages/mcp/src/client.ts#L109-L134

The file contains unresolved merge conflict markers:

<<<<<<< Updated upstream
=======
... askCodebase function ...
>>>>>>> Stashed changes

This will cause a syntax error. The conflict needs to be resolved by deciding whether to keep, remove, or merge the askCodebase function.

Issue 2: Merge conflict in packages/web/src/app/api/(server)/repos/route.ts

Location: Lines 1-9 (imports section)
Link:

<<<<<<< Updated upstream
import { NextRequest } from "next/server";
import { sew } from "@/actions";
import { withOptionalAuthV2 } from "@/withAuthV2";
=======
import { apiHandler } from "@/lib/apiHandler";
import { buildLinkHeader } from "@/lib/pagination";
import { listReposQueryParamsSchema } from "@/lib/schemas";
>>>>>>> Stashed changes
import { queryParamsSchemaValidationError, serviceErrorResponse } from "@/lib/serviceError";
import { isServiceError } from "@/lib/utils";
import { listReposQueryParamsSchema, repositoryQuerySchema } from "@/lib/schemas";
import { buildLinkHeader } from "@/lib/pagination";
import { getBrowsePath } from "@/app/[domain]/browse/hooks/utils";

The import section contains unresolved merge conflict markers:

<<<<<<< Updated upstream
import { NextRequest } from "next/server";
import { sew } from "@/actions";
import { withOptionalAuthV2 } from "@/withAuthV2";
=======
import { apiHandler } from "@/lib/apiHandler";
import { buildLinkHeader } from "@/lib/pagination";
import { listReposQueryParamsSchema } from "@/lib/schemas";
>>>>>>> Stashed changes

This will cause a syntax error. After the conflict markers, there are also duplicate imports that should be cleaned up once the conflict is resolved.


Action required: Please resolve these merge conflicts before the PR can be merged.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
packages/web/src/app/api/(server)/repos/route.ts (1)

42-44: ⚠️ Potential issue | 🟠 Major

Count query is missing the query filter, causing incorrect pagination.

The findMany query applies the query filter (line 34-36), but the count query only filters by orgId. This means totalCount will be the total repos for the org, not the filtered count, resulting in incorrect X-Total-Count and Link pagination headers when a search query is provided.

🐛 Proposed fix to include the query filter in count
             prisma.repo.count({
-                where: { orgId: org.id },
+                where: {
+                    orgId: org.id,
+                    ...(query ? {
+                        name: { contains: query, mode: 'insensitive' },
+                    } : {}),
+                },
             }),

@brendan-kellam brendan-kellam merged commit 6b79cbf into main Feb 1, 2026
9 checks passed
@brendan-kellam brendan-kellam deleted the bkellam/api-events branch February 1, 2026 05:18
@coderabbitai coderabbitai bot mentioned this pull request Feb 1, 2026
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