diff --git a/packages/kilo-gateway/src/api/constants.ts b/packages/kilo-gateway/src/api/constants.ts index f2f08dc92ad..1c9a72dcf40 100644 --- a/packages/kilo-gateway/src/api/constants.ts +++ b/packages/kilo-gateway/src/api/constants.ts @@ -27,8 +27,8 @@ export const DEFAULT_FREE_MODEL = "kilo-auto/free" /** Token expiration duration in milliseconds (1 year) */ export const TOKEN_EXPIRATION_MS = 365 * 24 * 60 * 60 * 1000 -/** User-Agent header value for requests */ -export const USER_AGENT = "opencode-kilo-provider" +/** User-Agent header base value for requests */ +export const USER_AGENT_BASE = "opencode-kilo-provider" /** Content-Type header value for requests */ export const CONTENT_TYPE = "application/json" diff --git a/packages/kilo-gateway/src/api/models.ts b/packages/kilo-gateway/src/api/models.ts index 8229966bf83..fb86344075d 100644 --- a/packages/kilo-gateway/src/api/models.ts +++ b/packages/kilo-gateway/src/api/models.ts @@ -1,6 +1,6 @@ import { z } from "zod" import { getKiloUrlFromToken } from "../auth/token.js" -import { DEFAULT_HEADERS } from "../headers.js" +import { getDefaultHeaders } from "../headers.js" import { KILO_API_BASE, KILO_OPENROUTER_BASE, MODELS_FETCH_TIMEOUT_MS, PROMPTS, AI_SDK_PROVIDERS } from "./constants.js" /** @@ -88,7 +88,7 @@ export async function fetchKiloModels(options?: { // Fetch models with timeout const response = await fetch(modelsURL, { headers: { - ...DEFAULT_HEADERS, + ...getDefaultHeaders(), ...(token ? { Authorization: `Bearer ${token}` } : {}), }, signal: AbortSignal.timeout(MODELS_FETCH_TIMEOUT_MS), diff --git a/packages/kilo-gateway/src/api/modes.ts b/packages/kilo-gateway/src/api/modes.ts index 18557ab50f4..85493804c52 100644 --- a/packages/kilo-gateway/src/api/modes.ts +++ b/packages/kilo-gateway/src/api/modes.ts @@ -1,6 +1,6 @@ import { z } from "zod" import { KILO_API_BASE, MODELS_FETCH_TIMEOUT_MS } from "./constants.js" -import { DEFAULT_HEADERS } from "../headers.js" +import { getDefaultHeaders } from "../headers.js" /** * Group entry in an organization mode config. @@ -70,7 +70,7 @@ export async function fetchOrganizationModes(token: string, organizationId: stri const url = `${KILO_API_BASE}/api/organizations/${encodeURIComponent(organizationId)}/modes` const response = await fetch(url, { headers: { - ...DEFAULT_HEADERS, + ...getDefaultHeaders(), Authorization: `Bearer ${token}`, }, signal: AbortSignal.timeout(MODELS_FETCH_TIMEOUT_MS), diff --git a/packages/kilo-gateway/src/headers.ts b/packages/kilo-gateway/src/headers.ts index 6170c427e7e..814f3d538d3 100644 --- a/packages/kilo-gateway/src/headers.ts +++ b/packages/kilo-gateway/src/headers.ts @@ -6,7 +6,7 @@ import { HEADER_EDITORNAME, HEADER_MACHINEID, HEADER_FEATURE, - USER_AGENT, + USER_AGENT_BASE, CONTENT_TYPE, DEFAULT_EDITOR_NAME, ENV_EDITOR_NAME, @@ -36,12 +36,23 @@ export function getFeatureHeader(): string | undefined { return process.env[ENV_FEATURE] || undefined } +/** + * Get User-Agent header value. + * Appends the version from KILOCODE_VERSION when available. + */ +export function getUserAgent(): string { + const version = process.env[ENV_VERSION] + return version ? `${USER_AGENT_BASE}/${version}` : USER_AGENT_BASE +} + /** * Default headers for KiloCode requests */ -export const DEFAULT_HEADERS = { - "User-Agent": USER_AGENT, - "Content-Type": CONTENT_TYPE, +export function getDefaultHeaders(): Record { + return { + "User-Agent": getUserAgent(), + "Content-Type": CONTENT_TYPE, + } } /** diff --git a/packages/kilo-gateway/src/index.ts b/packages/kilo-gateway/src/index.ts index c441cc5a6c1..04dbd7d5128 100644 --- a/packages/kilo-gateway/src/index.ts +++ b/packages/kilo-gateway/src/index.ts @@ -9,7 +9,7 @@ export { KiloAuthPlugin, default } from "./plugin.js" export { createKilo } from "./provider.js" export { createKiloDebug } from "./provider-debug.js" export { kiloCustomLoader } from "./loader.js" -export { buildKiloHeaders, getEditorNameHeader, getFeatureHeader, DEFAULT_HEADERS } from "./headers.js" +export { buildKiloHeaders, getEditorNameHeader, getFeatureHeader, getDefaultHeaders, getUserAgent } from "./headers.js" // ============================================================================ // Auth @@ -86,7 +86,7 @@ export { DEFAULT_MODEL, DEFAULT_FREE_MODEL, TOKEN_EXPIRATION_MS, - USER_AGENT, + USER_AGENT_BASE, CONTENT_TYPE, DEFAULT_PROVIDER_NAME, ANONYMOUS_API_KEY, diff --git a/packages/kilo-gateway/src/provider-debug.ts b/packages/kilo-gateway/src/provider-debug.ts index 240d8492fbf..37abac857b8 100644 --- a/packages/kilo-gateway/src/provider-debug.ts +++ b/packages/kilo-gateway/src/provider-debug.ts @@ -2,7 +2,7 @@ import { createOpenRouter } from "@openrouter/ai-sdk-provider" import type { Provider as SDK } from "ai" import type { KiloProviderOptions } from "./types.js" import { getKiloUrlFromToken, getApiKey } from "./auth/token.js" -import { buildKiloHeaders, DEFAULT_HEADERS } from "./headers.js" +import { buildKiloHeaders, getDefaultHeaders } from "./headers.js" import { KILO_API_BASE, ANONYMOUS_API_KEY } from "./api/constants.js" /** @@ -32,7 +32,7 @@ export function createKiloDebug(options: KiloProviderOptions = {}): SDK { // Merge custom headers with defaults const customHeaders = { - ...DEFAULT_HEADERS, + ...getDefaultHeaders(), ...buildKiloHeaders(undefined, { kilocodeOrganizationId: options.kilocodeOrganizationId, kilocodeTesterWarningsDisabledUntil: undefined, diff --git a/packages/kilo-gateway/src/provider.ts b/packages/kilo-gateway/src/provider.ts index 618360a4c35..e6a43bf0f42 100644 --- a/packages/kilo-gateway/src/provider.ts +++ b/packages/kilo-gateway/src/provider.ts @@ -4,7 +4,7 @@ import { createOpenAI } from "@ai-sdk/openai" import { createOpenAICompatible } from "@ai-sdk/openai-compatible" import type { KiloProvider, KiloProviderOptions } from "./types.js" import { getKiloUrlFromToken, getApiKey } from "./auth/token.js" -import { buildKiloHeaders, DEFAULT_HEADERS } from "./headers.js" +import { buildKiloHeaders, getDefaultHeaders } from "./headers.js" import { KILO_API_BASE, ANONYMOUS_API_KEY } from "./api/constants.js" /** @@ -39,7 +39,7 @@ export function createKilo(options: KiloProviderOptions = {}): KiloProvider { // Merge custom headers with defaults const customHeaders = { - ...DEFAULT_HEADERS, + ...getDefaultHeaders(), ...buildKiloHeaders(undefined, { kilocodeOrganizationId: options.kilocodeOrganizationId, kilocodeTesterWarningsDisabledUntil: undefined,