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
129 changes: 52 additions & 77 deletions src/api/providers/fetchers/openrouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,52 +101,33 @@ type OpenRouterModelEndpointsResponse = z.infer<typeof openRouterModelEndpointsR
export async function getOpenRouterModels(
options?: ApiHandlerOptions & { headers?: Record<string, string> }, // kilocode_change: added headers
): Promise<Record<string, ModelInfo>> {
// Return static models instead of making API calls
const models: Record<string, ModelInfo> = {}
const baseURL = "https://api.matterai.so/v1/web"

try {
// kilocode_change: use axios with timeout instead of fetch
const response = await axios.get(`${baseURL}/models`, {
headers: { ...DEFAULT_HEADERS, ...(options?.headers ?? {}) },
timeout: 120000, // 60 seconds timeout
// Import the static models from the shared file
const { KILO_CODE_MODELS } = await import("../kilocode-models")

for (const [id, model] of Object.entries(KILO_CODE_MODELS)) {
models[id] = parseOpenRouterModel({
id,
model: {
name: model.name,
description: model.description,
context_length: model.context_length,
max_completion_tokens: model.max_output_length,
pricing: {
prompt: model.pricing.prompt,
completion: model.pricing.completion,
input_cache_write: model.pricing.input_cache_writes,
input_cache_read: model.pricing.input_cache_reads,
},
},
displayName: model.name,
inputModality: model.input_modalities,
outputModality: model.output_modalities,
maxTokens: model.max_output_length,
supportedParameters: model.supported_sampling_parameters,
})

const json = response.data
const result = openRouterModelsResponseSchema.safeParse(json)
const data = result.success ? result.data.data : json.data
// kilocode_change end

if (!result.success) {
// kilocode_change start
throw new Error(
"OpenRouter models response is invalid: " + JSON.stringify(result.error.format(), undefined, 2),
)
// kilocode_change end
}

for (const model of data) {
const { id, architecture, top_provider, supported_parameters = [] } = model

// Skip image generation models (models that output images)
if (architecture?.output_modalities?.includes("image")) {
continue
}

models[id] = parseOpenRouterModel({
id,
model,
displayName: model.name, // kilocode_change
inputModality: architecture?.input_modalities,
outputModality: architecture?.output_modalities,
maxTokens: top_provider?.max_completion_tokens,
supportedParameters: supported_parameters,
})
}
} catch (error) {
console.error(
`Error fetching OpenRouter models: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`,
)
throw error // kilocode_change
}

return models
Expand All @@ -160,44 +141,38 @@ export async function getOpenRouterModelEndpoints(
modelId: string,
options?: ApiHandlerOptions,
): Promise<Record<string, ModelInfo>> {
// Return static models instead of making API calls
const models: Record<string, ModelInfo> = {}
const baseURL = "https://api.matterai.so/v1/web"

try {
console.log("getOpenRouterModelEndpoints 1", baseURL, modelId)
const response = await axios.get<OpenRouterModelEndpointsResponse>(`${baseURL}/models/${modelId}`, {
timeout: 120000, // 60 seconds timeout
})
const result = openRouterModelEndpointsResponseSchema.safeParse(response.data)
const data = result.success ? result.data.data : response.data.data

if (!result.success) {
console.error("OpenRouter model endpoints response is invalid", result.error.format())
}

const { id, architecture, endpoints } = data

// Skip image generation models (models that output images)
if (architecture?.output_modalities?.includes("image")) {
return models
}

for (const endpoint of endpoints) {
models[endpoint.tag ?? endpoint.provider_name] = parseOpenRouterModel({
id,
model: endpoint,
displayName: endpoint.model_name, // kilocode_change
inputModality: architecture?.input_modalities,
outputModality: architecture?.output_modalities,
maxTokens: endpoint.max_completion_tokens,
})
}
} catch (error) {
console.error(
`Error fetching OpenRouter model endpoints: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`,
)
// Import the static models from the shared file
const { KILO_CODE_MODELS } = await import("../kilocode-models")

const model = KILO_CODE_MODELS[modelId]
if (!model) {
return models
}

models["KiloCode"] = parseOpenRouterModel({
id: model.id,
model: {
name: model.name,
description: model.description,
context_length: model.context_length,
max_completion_tokens: model.max_output_length,
pricing: {
prompt: model.pricing.prompt,
completion: model.pricing.completion,
input_cache_write: model.pricing.input_cache_writes,
input_cache_read: model.pricing.input_cache_reads,
},
},
displayName: model.name,
inputModality: model.input_modalities,
outputModality: model.output_modalities,
maxTokens: model.max_output_length,
supportedParameters: model.supported_sampling_parameters,
})

return models
}

Expand Down
133 changes: 133 additions & 0 deletions src/api/providers/kilocode-models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import type { ModelParameter } from "@roo-code/types"

export type KiloCodeModel = {
id: string
name: string
description: string
input_modalities: string[]
context_length: number
max_output_length: number
output_modalities: string[]
supported_sampling_parameters: string[]
supported_features: string[]
openrouter: {
slug: string
}
datacenters: Array<{ country_code: string }>
created: number
owned_by: string
pricing: {
prompt?: string
completion?: string
image?: string
request?: string
input_cache_reads?: string
input_cache_writes?: string
}
}

export const KILO_CODE_MODELS: Record<string, KiloCodeModel> = {
"axon-code": {
id: "axon-code",
name: "Axon Code",
description: "Axon Code is super intelligent LLM model for coding tasks",
input_modalities: ["text"],
context_length: 256000,
max_output_length: 32768,
output_modalities: ["text"],
supported_sampling_parameters: [
"temperature",
"top_p",
"top_k",
"repetition_penalty",
"frequency_penalty",
"presence_penalty",
"seed",
"stop",
],
supported_features: ["tools", "structured_outputs", "web_search"],
openrouter: {
slug: "matterai/axon",
},
datacenters: [{ country_code: "US" }],
created: 1750426201,
owned_by: "matterai",
pricing: {
prompt: "0.000001",
completion: "0.000004",
image: "0",
request: "0",
input_cache_reads: "0",
input_cache_writes: "0",
},
},
"axon-mini": {
id: "axon-mini",
name: "Axon Mini",
description:
"Axon Mini is an general purpose super intelligent LLM coding model for low-effort day-to-day tasks",
input_modalities: ["text"],
context_length: 256000,
max_output_length: 16384,
output_modalities: ["text"],
supported_sampling_parameters: [
"temperature",
"top_p",
"top_k",
"repetition_penalty",
"frequency_penalty",
"presence_penalty",
"seed",
"stop",
],
supported_features: ["tools", "structured_outputs", "web_search"],
openrouter: {
slug: "matterai/axon",
},
datacenters: [{ country_code: "US" }],
created: 1750426201,
owned_by: "matterai",
pricing: {
prompt: "2.5e-7",
completion: "0.000001",
image: "0",
request: "0",
input_cache_reads: "0",
input_cache_writes: "0",
},
},
// "axon-code-pro": {
// id: "axon-code-pro",
// name: "Axon Code Pro",
// description: "Axon Code Pro is a heavy intelligent LLM model for coding tasks",
// input_modalities: ["text"],
// context_length: 256000,
// max_output_length: 32768,
// output_modalities: ["text"],
// supported_sampling_parameters: [
// "temperature",
// "top_p",
// "top_k",
// "repetition_penalty",
// "frequency_penalty",
// "presence_penalty",
// "seed",
// "stop",
// ],
// supported_features: ["tools", "structured_outputs", "web_search"],
// openrouter: {
// slug: "matterai/axon",
// },
// datacenters: [{ country_code: "US" }],
// created: 1750426201,
// owned_by: "matterai",
// pricing: {
// prompt: "0.000001",
// completion: "0.000004",
// image: "0",
// request: "0",
// input_cache_reads: "0",
// input_cache_writes: "0",
// },
// },
}
Loading
Loading