Skip to content

Commit 9b0f3b2

Browse files
authored
feat: add User-Agent header to API providers (#5492)
1 parent fa60a31 commit 9b0f3b2

File tree

5 files changed

+70
-0
lines changed

5 files changed

+70
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// npx vitest run src/api/providers/__tests__/constants.spec.ts
2+
3+
import { describe, it, expect } from "vitest"
4+
import { DEFAULT_HEADERS } from "../constants"
5+
import { Package } from "../../../shared/package"
6+
7+
describe("DEFAULT_HEADERS", () => {
8+
it("should contain all required headers", () => {
9+
expect(DEFAULT_HEADERS).toHaveProperty("HTTP-Referer")
10+
expect(DEFAULT_HEADERS).toHaveProperty("X-Title")
11+
expect(DEFAULT_HEADERS).toHaveProperty("User-Agent")
12+
})
13+
14+
it("should have correct HTTP-Referer value", () => {
15+
expect(DEFAULT_HEADERS["HTTP-Referer"]).toBe("https://github.com/RooVetGit/Roo-Cline")
16+
})
17+
18+
it("should have correct X-Title value", () => {
19+
expect(DEFAULT_HEADERS["X-Title"]).toBe("Roo Code")
20+
})
21+
22+
it("should have correct User-Agent format", () => {
23+
const userAgent = DEFAULT_HEADERS["User-Agent"]
24+
expect(userAgent).toBe(`RooCode/${Package.version}`)
25+
26+
// Verify it follows the tool_name/version pattern
27+
expect(userAgent).toMatch(/^[a-zA-Z-]+\/\d+\.\d+\.\d+$/)
28+
})
29+
30+
it("should have User-Agent with correct tool name", () => {
31+
const userAgent = DEFAULT_HEADERS["User-Agent"]
32+
expect(userAgent.startsWith("RooCode/")).toBe(true)
33+
})
34+
35+
it("should have User-Agent with semantic version format", () => {
36+
const userAgent = DEFAULT_HEADERS["User-Agent"]
37+
const version = userAgent.split("/")[1]
38+
39+
// Check semantic version format (major.minor.patch)
40+
expect(version).toMatch(/^\d+\.\d+\.\d+$/)
41+
42+
// Verify current version matches package version
43+
expect(version).toBe(Package.version)
44+
})
45+
46+
it("should be an object with string values", () => {
47+
expect(typeof DEFAULT_HEADERS).toBe("object")
48+
expect(DEFAULT_HEADERS).not.toBeNull()
49+
50+
Object.values(DEFAULT_HEADERS).forEach((value) => {
51+
expect(typeof value).toBe("string")
52+
expect(value.length).toBeGreaterThan(0)
53+
})
54+
})
55+
56+
it("should have exactly 3 headers", () => {
57+
const headerKeys = Object.keys(DEFAULT_HEADERS)
58+
expect(headerKeys).toHaveLength(3)
59+
expect(headerKeys).toEqual(["HTTP-Referer", "X-Title", "User-Agent"])
60+
})
61+
})

src/api/providers/__tests__/openai.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ApiHandlerOptions } from "../../../shared/api"
55
import { Anthropic } from "@anthropic-ai/sdk"
66
import OpenAI from "openai"
77
import { openAiModelInfoSaneDefaults } from "@roo-code/types"
8+
import { Package } from "../../../shared/package"
89

910
const mockCreate = vitest.fn()
1011

@@ -104,6 +105,7 @@ describe("OpenAiHandler", () => {
104105
defaultHeaders: {
105106
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
106107
"X-Title": "Roo Code",
108+
"User-Agent": `RooCode/${Package.version}`,
107109
},
108110
})
109111
})

src/api/providers/__tests__/openrouter.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import OpenAI from "openai"
88

99
import { OpenRouterHandler } from "../openrouter"
1010
import { ApiHandlerOptions } from "../../../shared/api"
11+
import { Package } from "../../../shared/package"
1112

1213
// Mock dependencies
1314
vitest.mock("openai")
@@ -62,6 +63,7 @@ describe("OpenRouterHandler", () => {
6263
defaultHeaders: {
6364
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
6465
"X-Title": "Roo Code",
66+
"User-Agent": `RooCode/${Package.version}`,
6567
},
6668
})
6769
})

src/api/providers/__tests__/requesty.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import OpenAI from "openai"
55

66
import { RequestyHandler } from "../requesty"
77
import { ApiHandlerOptions } from "../../../shared/api"
8+
import { Package } from "../../../shared/package"
89

910
const mockCreate = vitest.fn()
1011

@@ -59,6 +60,7 @@ describe("RequestyHandler", () => {
5960
defaultHeaders: {
6061
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
6162
"X-Title": "Roo Code",
63+
"User-Agent": `RooCode/${Package.version}`,
6264
},
6365
})
6466
})

src/api/providers/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
import { Package } from "../../shared/package"
2+
13
export const DEFAULT_HEADERS = {
24
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
35
"X-Title": "Roo Code",
6+
"User-Agent": `RooCode/${Package.version}`,
47
}

0 commit comments

Comments
 (0)