Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/wise-pears-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"roo-cline": patch
---

Improved observability of openai compatible APIs, by sending x-title and http-referer headers, as per Open Router standard.
14 changes: 14 additions & 0 deletions src/api/providers/__tests__/openai.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,20 @@ describe("OpenAiHandler", () => {
})
expect(handlerWithCustomUrl).toBeInstanceOf(OpenAiHandler)
})

it("should set default headers correctly", () => {
// Get the mock constructor from the jest mock system
const openAiMock = jest.requireMock("openai").default

expect(openAiMock).toHaveBeenCalledWith({
baseURL: expect.any(String),
apiKey: expect.any(String),
defaultHeaders: {
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
"X-Title": "Roo Code",
},
})
})
})

describe("createMessage", () => {
Expand Down
11 changes: 8 additions & 3 deletions src/api/providers/openai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ import { ApiStream, ApiStreamUsageChunk } from "../transform/stream"
import { BaseProvider } from "./base-provider"

const DEEP_SEEK_DEFAULT_TEMPERATURE = 0.6
export interface OpenAiHandlerOptions extends ApiHandlerOptions {
defaultHeaders?: Record<string, string>

export const defaultHeaders = {
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
"X-Title": "Roo Code",
}

export interface OpenAiHandlerOptions extends ApiHandlerOptions {}

export class OpenAiHandler extends BaseProvider implements SingleCompletionHandler {
protected options: OpenAiHandlerOptions
private client: OpenAI
Expand Down Expand Up @@ -47,9 +51,10 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl
baseURL,
apiKey,
apiVersion: this.options.azureApiVersion || azureOpenAiDefaultApiVersion,
defaultHeaders,
})
} else {
this.client = new OpenAI({ baseURL, apiKey, defaultHeaders: this.options.defaultHeaders })
this.client = new OpenAI({ baseURL, apiKey, defaultHeaders })
}
}

Expand Down
6 changes: 1 addition & 5 deletions src/api/providers/openrouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { convertToR1Format } from "../transform/r1-format"
import { DEEP_SEEK_DEFAULT_TEMPERATURE } from "./constants"
import { getModelParams, SingleCompletionHandler } from ".."
import { BaseProvider } from "./base-provider"
import { defaultHeaders } from "./openai"

// Add custom interface for OpenRouter params.
type OpenRouterChatCompletionParams = OpenAI.Chat.ChatCompletionCreateParams & {
Expand All @@ -37,11 +38,6 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
const baseURL = this.options.openRouterBaseUrl || "https://openrouter.ai/api/v1"
const apiKey = this.options.openRouterApiKey ?? "not-provided"

const defaultHeaders = {
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
"X-Title": "Roo Code",
}

this.client = new OpenAI({ baseURL, apiKey, defaultHeaders })
}

Expand Down
4 changes: 0 additions & 4 deletions src/api/providers/requesty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ export class RequestyHandler extends OpenAiHandler {
openAiModelId: options.requestyModelId ?? requestyDefaultModelId,
openAiBaseUrl: "https://router.requesty.ai/v1",
openAiCustomModelInfo: options.requestyModelInfo ?? requestyModelInfoSaneDefaults,
defaultHeaders: {
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
"X-Title": "Roo Code",
},
})
}

Expand Down
Loading