Skip to content

Commit 6b79cbf

Browse files
chore(web): Add telemetry for all api requests (#835)
1 parent 97f2810 commit 6b79cbf

File tree

28 files changed

+172
-71
lines changed

28 files changed

+172
-71
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212

1313
### Changed
1414
- Changed `/api/source` api to support fetching source code for any revision, not just revisions that are indexed by zoekt. [#829](https://github.com/sourcebot-dev/sourcebot/pull/829)
15+
- Added additional telemetry for api requests. [#835](https://github.com/sourcebot-dev/sourcebot/pull/835)
1516

1617
## [4.10.20] - 2026-01-28
1718

packages/mcp/src/client.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const search = async (request: SearchRequest) => {
3535
method: 'POST',
3636
headers: {
3737
'Content-Type': 'application/json',
38+
'X-Sourcebot-Client-Source': 'mcp',
3839
...(env.SOURCEBOT_API_KEY ? { 'X-Sourcebot-Api-Key': env.SOURCEBOT_API_KEY } : {})
3940
},
4041
body: JSON.stringify(request)
@@ -56,6 +57,7 @@ export const listRepos = async (queryParams: ListReposQueryParams = {}) => {
5657
method: 'GET',
5758
headers: {
5859
'Content-Type': 'application/json',
60+
'X-Sourcebot-Client-Source': 'mcp',
5961
...(env.SOURCEBOT_API_KEY ? { 'X-Sourcebot-Api-Key': env.SOURCEBOT_API_KEY } : {})
6062
},
6163
});
@@ -76,6 +78,7 @@ export const getFileSource = async (request: FileSourceRequest) => {
7678
const response = await fetch(url, {
7779
method: 'GET',
7880
headers: {
81+
'X-Sourcebot-Client-Source': 'mcp',
7982
...(env.SOURCEBOT_API_KEY ? { 'X-Sourcebot-Api-Key': env.SOURCEBOT_API_KEY } : {})
8083
},
8184
});
@@ -95,11 +98,12 @@ export const listCommits = async (queryParams: ListCommitsQueryParamsSchema) =>
9598
method: 'GET',
9699
headers: {
97100
'X-Org-Domain': '~',
101+
'X-Sourcebot-Client-Source': 'mcp',
98102
...(env.SOURCEBOT_API_KEY ? { 'X-Sourcebot-Api-Key': env.SOURCEBOT_API_KEY } : {})
99103
},
100104
});
101105

102106
const commits = await parseResponse(response, listCommitsResponseSchema);
103107
const totalCount = parseInt(response.headers.get('X-Total-Count') ?? '0', 10);
104108
return { commits, totalCount };
105-
}
109+
}

packages/mcp/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ server.tool(
101101
contextLines: env.DEFAULT_CONTEXT_LINES,
102102
isRegexEnabled: useRegex,
103103
isCaseSensitivityEnabled: caseSensitive,
104-
source: 'mcp',
105104
});
106105

107106
if (response.files.length === 0) {

packages/mcp/src/schemas.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ export const searchOptionsSchema = z.object({
3131

3232
export const searchRequestSchema = z.object({
3333
query: z.string(), // The zoekt query to execute.
34-
source: z.string().optional(), // The source of the search request.
3534
...searchOptionsSchema.shape,
3635
});
3736

packages/web/src/app/[domain]/components/searchBar/useSuggestionsData.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ export const useSuggestionsData = ({
6161
query: `file:${suggestionQuery}`,
6262
matches: 15,
6363
contextLines: 1,
64-
source: 'search-bar-file-suggestions'
6564
}),
6665
select: (data): Suggestion[] => {
6766
if (isServiceError(data)) {
@@ -82,7 +81,6 @@ export const useSuggestionsData = ({
8281
query: `sym:${suggestionQuery.length > 0 ? suggestionQuery : ".*"}`,
8382
matches: 15,
8483
contextLines: 1,
85-
source: 'search-bar-symbol-suggestions'
8684
}),
8785
select: (data): Suggestion[] => {
8886
if (isServiceError(data)) {

packages/web/src/app/[domain]/search/useStreamedSearch.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
121121
method: 'POST',
122122
headers: {
123123
'Content-Type': 'application/json',
124+
'X-Sourcebot-Client-Source': 'sourcebot-web-client',
124125
},
125126
body: JSON.stringify({
126127
query,
@@ -129,7 +130,6 @@ export const useStreamedSearch = ({ query, matches, contextLines, whole, isRegex
129130
whole,
130131
isRegexEnabled,
131132
isCaseSensitivityEnabled,
132-
source: 'sourcebot-web-client'
133133
} satisfies SearchRequest),
134134
signal: abortControllerRef.current.signal,
135135
});

packages/web/src/app/api/(client)/client.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const search = async (body: SearchRequest): Promise<SearchResponse | Serv
2525
method: "POST",
2626
headers: {
2727
"Content-Type": "application/json",
28+
"X-Sourcebot-Client-Source": "sourcebot-web-client",
2829
},
2930
body: JSON.stringify(body),
3031
}).then(response => response.json());
@@ -44,6 +45,9 @@ export const getFileSource = async (queryParams: FileSourceRequest): Promise<Fil
4445

4546
const result = await fetch(url, {
4647
method: "GET",
48+
headers: {
49+
"X-Sourcebot-Client-Source": "sourcebot-web-client",
50+
}
4751
}).then(response => response.json());
4852

4953
return result as FileSourceResponse | ServiceError;
@@ -59,6 +63,7 @@ export const listRepos = async (queryParams: ListReposQueryParams): Promise<List
5963
method: "GET",
6064
headers: {
6165
"Content-Type": "application/json",
66+
"X-Sourcebot-Client-Source": "sourcebot-web-client",
6267
},
6368
}).then(response => response.json());
6469

@@ -70,6 +75,7 @@ export const getVersion = async (): Promise<GetVersionResponse> => {
7075
method: "GET",
7176
headers: {
7277
"Content-Type": "application/json",
78+
"X-Sourcebot-Client-Source": "sourcebot-web-client",
7379
},
7480
}).then(response => response.json());
7581
return result as GetVersionResponse;
@@ -78,6 +84,9 @@ export const getVersion = async (): Promise<GetVersionResponse> => {
7884
export const findSearchBasedSymbolReferences = async (body: FindRelatedSymbolsRequest): Promise<FindRelatedSymbolsResponse | ServiceError> => {
7985
const result = await fetch("/api/find_references", {
8086
method: "POST",
87+
headers: {
88+
"X-Sourcebot-Client-Source": "sourcebot-web-client",
89+
},
8190
body: JSON.stringify(body),
8291
}).then(response => response.json());
8392
return result as FindRelatedSymbolsResponse | ServiceError;
@@ -86,6 +95,9 @@ export const findSearchBasedSymbolReferences = async (body: FindRelatedSymbolsRe
8695
export const findSearchBasedSymbolDefinitions = async (body: FindRelatedSymbolsRequest): Promise<FindRelatedSymbolsResponse | ServiceError> => {
8796
const result = await fetch("/api/find_definitions", {
8897
method: "POST",
98+
headers: {
99+
"X-Sourcebot-Client-Source": "sourcebot-web-client",
100+
},
89101
body: JSON.stringify(body),
90102
}).then(response => response.json());
91103
return result as FindRelatedSymbolsResponse | ServiceError;
@@ -94,6 +106,9 @@ export const findSearchBasedSymbolDefinitions = async (body: FindRelatedSymbolsR
94106
export const getTree = async (body: GetTreeRequest): Promise<GetTreeResponse | ServiceError> => {
95107
const result = await fetch("/api/tree", {
96108
method: "POST",
109+
headers: {
110+
"X-Sourcebot-Client-Source": "sourcebot-web-client",
111+
},
97112
body: JSON.stringify(body),
98113
}).then(response => response.json());
99114
return result as GetTreeResponse | ServiceError;
@@ -102,6 +117,9 @@ export const getTree = async (body: GetTreeRequest): Promise<GetTreeResponse | S
102117
export const getFiles = async (body: GetFilesRequest): Promise<GetFilesResponse | ServiceError> => {
103118
const result = await fetch("/api/files", {
104119
method: "POST",
120+
headers: {
121+
"X-Sourcebot-Client-Source": "sourcebot-web-client",
122+
},
105123
body: JSON.stringify(body),
106124
}).then(response => response.json());
107125
return result as GetFilesResponse | ServiceError;

packages/web/src/app/api/(server)/chat/route.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { _getConfiguredLanguageModelsFull, _getAISDKLanguageModelAndOptions, upd
33
import { createAgentStream } from "@/features/chat/agent";
44
import { additionalChatRequestParamsSchema, LanguageModelInfo, SBChatMessage, SearchScope } from "@/features/chat/types";
55
import { getAnswerPartFromAssistantMessage, getLanguageModelKey } from "@/features/chat/utils";
6+
import { apiHandler } from "@/lib/apiHandler";
67
import { ErrorCode } from "@/lib/errorCodes";
78
import { notFound, requestBodySchemaValidationError, serviceErrorResponse } from "@/lib/serviceError";
89
import { isServiceError } from "@/lib/utils";
@@ -22,6 +23,7 @@ import {
2223
} from "ai";
2324
import { randomUUID } from "crypto";
2425
import { StatusCodes } from "http-status-codes";
26+
import { NextRequest } from "next/server";
2527
import { z } from "zod";
2628

2729
const logger = createLogger('chat-api');
@@ -33,7 +35,7 @@ const chatRequestSchema = z.object({
3335
...additionalChatRequestParamsSchema.shape,
3436
})
3537

36-
export async function POST(req: Request) {
38+
export const POST = apiHandler(async (req: NextRequest) => {
3739
const requestBody = await req.json();
3840
const parsed = await chatRequestSchema.safeParseAsync(requestBody);
3941
if (!parsed.success) {
@@ -102,7 +104,7 @@ export async function POST(req: Request) {
102104
}
103105

104106
return response;
105-
}
107+
});
106108

107109
// eslint-disable-next-line @typescript-eslint/no-explicit-any
108110
const mergeStreamAsync = async (stream: StreamTextResult<any, any>, writer: UIMessageStreamWriter<SBChatMessage>, options: UIMessageStreamOptions<SBChatMessage> = {}) => {

packages/web/src/app/api/(server)/commits/route.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { listCommits } from "@/features/git";
2+
import { apiHandler } from "@/lib/apiHandler";
23
import { buildLinkHeader } from "@/lib/pagination";
34
import { serviceErrorResponse, queryParamsSchemaValidationError } from "@/lib/serviceError";
45
import { isServiceError } from "@/lib/utils";
@@ -16,7 +17,7 @@ const listCommitsQueryParamsSchema = z.object({
1617
perPage: z.coerce.number().int().positive().max(100).default(50),
1718
});
1819

19-
export const GET = async (request: NextRequest): Promise<Response> => {
20+
export const GET = apiHandler(async (request: NextRequest): Promise<Response> => {
2021
const rawParams = Object.fromEntries(
2122
Object.keys(listCommitsQueryParamsSchema.shape).map(key => [
2223
key,
@@ -61,4 +62,4 @@ export const GET = async (request: NextRequest): Promise<Response> => {
6162
if (linkHeader) headers.set('Link', linkHeader);
6263

6364
return new Response(JSON.stringify(commits), { status: 200, headers });
64-
}
65+
});

packages/web/src/app/api/(server)/ee/audit/route.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
'use server';
22

33
import { fetchAuditRecords } from "@/ee/features/audit/actions";
4+
import { apiHandler } from "@/lib/apiHandler";
45
import { ErrorCode } from "@/lib/errorCodes";
56
import { serviceErrorResponse } from "@/lib/serviceError";
67
import { isServiceError } from "@/lib/utils";
78
import { getEntitlements } from "@sourcebot/shared";
89
import { StatusCodes } from "http-status-codes";
910

10-
export const GET = async () => {
11+
export const GET = apiHandler(async () => {
1112
const entitlements = getEntitlements();
1213
if (!entitlements.includes('audit')) {
1314
return serviceErrorResponse({
@@ -22,4 +23,4 @@ export const GET = async () => {
2223
return serviceErrorResponse(result);
2324
}
2425
return Response.json(result);
25-
};
26+
});

0 commit comments

Comments
 (0)