Skip to content

Commit 64c34c9

Browse files
kirill-markinclaude
andcommitted
feat(chat): send the client platform when starting a chat run
Web, iOS and Android now send X-Client-Platform (web, ios, android, the same values their live stream already sends) on POST /chat, so the backend can attribute AI chat reviews to the device. No other request changes. The API gateway already allows the header, and a backend that does not read it ignores it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 61fe27d commit 64c34c9

4 files changed

Lines changed: 11 additions & 6 deletions

File tree

apps/android/data/local/src/main/java/com/flashcardsopensourceapp/data/local/ai/remote/AiChatLiveRemoteService.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import java.util.concurrent.atomic.AtomicBoolean
3131
const val aiChatLiveStreamEndedBeforeTerminalCode: String = "ai_live_stream_ended_before_terminal"
3232
const val aiChatLiveStreamReadFailedCode: String = "ai_live_stream_read_failed"
3333

34-
private const val aiChatLiveClientPlatform: String = "android"
34+
internal const val aiChatClientPlatform: String = "android"
3535

3636
private const val aiChatLiveAttachThrottleStatusCode: Int = 429
3737

@@ -227,7 +227,7 @@ class AiChatLiveRemoteService private constructor(
227227
.cacheControl(CacheControl.FORCE_NETWORK)
228228
.header("Accept", "text/event-stream")
229229
.header("Authorization", authorization)
230-
.header("X-Client-Platform", aiChatLiveClientPlatform)
230+
.header("X-Client-Platform", aiChatClientPlatform)
231231
.header("X-Chat-Live-Client-Id", aiChatLiveClientId)
232232
val clientVersion = observationVersions.clientVersion
233233
if (clientVersion != null) {

apps/android/data/local/src/main/java/com/flashcardsopensourceapp/data/local/ai/remote/AiChatRemoteService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ class AiChatRemoteService private constructor(
388388
method = "POST",
389389
authorizationHeader = authorizationHeader,
390390
requestBody = requestJson.toRequestBody(aiJsonMediaType),
391-
extraHeaders = emptyMap()
391+
extraHeaders = mapOf("X-Client-Platform" to aiChatClientPlatform)
392392
)
393393
)
394394
return@withContext decodeAiChatStartRunResponse(responseBody)

apps/ios/Flashcards/Flashcards/AI/Runtime/AIChatService.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,8 @@ final class AIChatService: AIChatSessionServicing, @unchecked Sendable {
370370
path: "/chat",
371371
method: "POST",
372372
bodyData: encodedBody,
373-
clientRequestId: clientRequestId
373+
clientRequestId: clientRequestId,
374+
additionalHeaders: ["X-Client-Platform": aiChatClientPlatform]
374375
)
375376
let data = try await self.execute(
376377
session: session,
@@ -606,14 +607,15 @@ final class AIChatService: AIChatSessionServicing, @unchecked Sendable {
606607
path: String,
607608
method: String,
608609
bodyData: Data,
609-
clientRequestId: String
610+
clientRequestId: String,
611+
additionalHeaders: [String: String]
610612
) throws -> URLRequest {
611613
var request = try self.makeRequest(
612614
session: session,
613615
path: path,
614616
method: method,
615617
clientRequestId: clientRequestId,
616-
additionalHeaders: [:]
618+
additionalHeaders: additionalHeaders
617619
)
618620
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
619621
request.httpBody = bodyData

apps/web/src/api/endpoints/chat.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ export async function getChatSnapshotWithResumeDiagnostics(
6868
export async function startChatRun(body: StartChatRunRequestBody): Promise<StartChatRunResponse> {
6969
return parseContractResponse(await requestJson("/chat", {
7070
method: "POST",
71+
headers: {
72+
"X-Client-Platform": "web",
73+
},
7174
body: JSON.stringify(body),
7275
}, allowAuthRecoveryWithTransientNetworkRetry), "POST /chat", parseStartChatRunResponse);
7376
}

0 commit comments

Comments
 (0)