Skip to content
Open
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/good-towns-argue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"kilo-code": minor
---

Synthetic provider to use updated models endpoint and dynamic fetcher
1 change: 1 addition & 0 deletions packages/types/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export const modelInfoSchema = z.object({
maxThinkingTokens: z.number().nullish(),
contextWindow: z.number(),
supportsImages: z.boolean().optional(),
supportsComputerUse: z.boolean().optional(),
supportsPromptCache: z.boolean(),
// Capability flag to indicate whether the model supports an output verbosity parameter
supportsVerbosity: z.boolean().optional(),
Expand Down
1 change: 1 addition & 0 deletions packages/types/src/provider-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export const dynamicProviders = [
"requesty",
"unbound",
"glama",
"synthetic",
"roo",
"chutes",
] as const
Expand Down
219 changes: 11 additions & 208 deletions packages/types/src/providers/synthetic.ts
Original file line number Diff line number Diff line change
@@ -1,221 +1,24 @@
// kilocode_change: provider added
// kilocode_change: provider added - dynamic models only

import type { ModelInfo } from "../model.js"

export type SyntheticModelId =
| "hf:MiniMaxAI/MiniMax-M2"
| "hf:zai-org/GLM-4.6"
| "hf:zai-org/GLM-4.5"
| "hf:openai/gpt-oss-120b"
| "hf:moonshotai/Kimi-K2-Instruct-0905"
| "hf:moonshotai/Kimi-K2-Thinking"
| "hf:reissbaker/llama-3.1-70b-abliterated-lora"
| "hf:meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8"
| "hf:deepseek-ai/DeepSeek-V3.1"
| "hf:meta-llama/Llama-3.1-8B-Instruct"
| "hf:meta-llama/Llama-3.1-70B-Instruct"
| "hf:meta-llama/Llama-3.1-405B-Instruct"
| "hf:meta-llama/Llama-3.3-70B-Instruct"
| "hf:deepseek-ai/DeepSeek-V3-0324"
| "hf:deepseek-ai/DeepSeek-R1"
| "hf:moonshotai/Kimi-K2-Instruct"
| "hf:meta-llama/Llama-4-Scout-17B-16E-Instruct"
| "hf:Qwen/Qwen3-Coder-480B-A35B-Instruct"
| "hf:Qwen/Qwen2.5-Coder-32B-Instruct"
| "hf:Qwen/Qwen3-235B-A22B-Thinking-2507"
| "hf:Qwen/Qwen3-235B-A22B-Instruct-2507"
export type SyntheticModelId = string

export const syntheticDefaultModelId: SyntheticModelId = "hf:zai-org/GLM-4.6"
export const syntheticDefaultModelId = "hf:zai-org/GLM-4.6"

export const syntheticModels = {
"hf:MiniMaxAI/MiniMax-M2": {
maxTokens: 192608,
contextWindow: 192608,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.55,
outputPrice: 2.19,
description:
"MiniMax's latest hybrid reasoning model: it's fast, it thinks before it responds, it's great at using tools via the API, and it's a strong coding model. 192k-token context.",
},
"hf:moonshotai/Kimi-K2-Thinking": {
maxTokens: 262144,
contextWindow: 262144,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.55,
outputPrice: 2.19,
description:
"Moonshot's latest hybrid reasoner. Extremely good at math — it saturates the AIME25 math benchmark — and competitive with GPT-5 and Claude 4.5 at tool use and codegen. 256k-token context.",
},
"hf:moonshotai/Kimi-K2-Instruct-0905": {
maxTokens: 262144,
contextWindow: 262144,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 1.2,
outputPrice: 1.2,
description:
"Kimi K2 model gets a new version update: Agentic coding: more accurate, better generalization across scaffolds. Frontend coding: improved aesthetics and functionalities on web, 3d, and other tasks. Context length: extended from 128k to 256k, providing better long-horizon support.",
},
"hf:openai/gpt-oss-120b": {
maxTokens: 128000,
contextWindow: 128000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.1,
outputPrice: 0.1,
},
"hf:zai-org/GLM-4.5": {
maxTokens: 128000,
contextWindow: 128000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.55,
outputPrice: 2.19,
},
// Models used in tests and as fallback for dynamic provider
export const syntheticModels: Record<string, ModelInfo> = {
"hf:zai-org/GLM-4.6": {
maxTokens: 200000,
contextWindow: 200000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.55,
outputPrice: 2.19,
},
"hf:reissbaker/llama-3.1-70b-abliterated-lora": {
maxTokens: 128000,
contextWindow: 128000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.9,
outputPrice: 0.9,
},
"hf:meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8": {
maxTokens: 524000,
contextWindow: 524000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.22,
outputPrice: 0.88,
},
"hf:deepseek-ai/DeepSeek-V3.1": {
maxTokens: 128000,
contextWindow: 128000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.56,
outputPrice: 1.68,
},
"hf:meta-llama/Llama-3.1-405B-Instruct": {
maxTokens: 128000,
contextWindow: 128000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 3.0,
outputPrice: 3.0,
},
"hf:meta-llama/Llama-3.1-70B-Instruct": {
maxTokens: 128000,
contextWindow: 128000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.9,
outputPrice: 0.9,
},
"hf:meta-llama/Llama-3.1-8B-Instruct": {
maxTokens: 128000,
contextWindow: 128000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.2,
outputPrice: 0.2,
},
"hf:meta-llama/Llama-3.3-70B-Instruct": {
maxTokens: 128000,
contextWindow: 128000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.9,
outputPrice: 0.9,
},
"hf:deepseek-ai/DeepSeek-V3-0324": {
maxTokens: 128000,
contextWindow: 128000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 1.2,
outputPrice: 1.2,
},
"hf:deepseek-ai/DeepSeek-R1": {
maxTokens: 128000,
contextWindow: 128000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.55,
outputPrice: 2.19,
description: "GLM-4.6",
supportsComputerUse: false,
supportsReasoningEffort: false,
supportsReasoningBudget: false,
supportedParameters: [],
},
"hf:deepseek-ai/DeepSeek-R1-0528": {
maxTokens: 128000,
contextWindow: 128000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 3.0,
outputPrice: 8.0,
},
"hf:meta-llama/Llama-4-Scout-17B-16E-Instruct": {
maxTokens: 328000,
contextWindow: 328000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.15,
outputPrice: 0.6,
},
"hf:moonshotai/Kimi-K2-Instruct": {
maxTokens: 128000,
contextWindow: 128000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.6,
outputPrice: 2.5,
},
"hf:Qwen/Qwen3-Coder-480B-A35B-Instruct": {
maxTokens: 256000,
contextWindow: 256000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.45,
outputPrice: 1.8,
},
"hf:Qwen/Qwen2.5-Coder-32B-Instruct": {
maxTokens: 32000,
contextWindow: 32000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.8,
outputPrice: 0.8,
},
"hf:deepseek-ai/DeepSeek-V3": {
maxTokens: 128000,
contextWindow: 128000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 1.25,
outputPrice: 1.25,
},
"hf:Qwen/Qwen3-235B-A22B-Instruct-2507": {
maxTokens: 256000,
contextWindow: 256000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.22,
outputPrice: 0.88,
},
"hf:Qwen/Qwen3-235B-A22B-Thinking-2507": {
maxTokens: 256000,
contextWindow: 256000,
supportsImages: false,
supportsPromptCache: false,
inputPrice: 0.65,
outputPrice: 3.0,
},
} as const satisfies Record<string, ModelInfo>
}
19 changes: 14 additions & 5 deletions src/api/providers/__tests__/synthetic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,21 @@ vi.mock("openai", () => ({
})),
}))

// Mock model cache
vi.mock("../fetchers/modelCache", () => ({
getModels: vi.fn(),
}))

// Import the mocked function after mock setup
const { getModels: mockGetModels } = await import("../fetchers/modelCache")

describe("SyntheticHandler", () => {
let handler: SyntheticHandler

beforeEach(() => {
vi.clearAllMocks()
// Mock getModels to return the static models
vi.mocked(mockGetModels).mockResolvedValue(syntheticModels)
// Set up default mock implementation
mockCreate.mockImplementation(async () => ({
[Symbol.asyncIterator]: async function* () {
Expand Down Expand Up @@ -83,7 +93,7 @@ describe("SyntheticHandler", () => {
})

it("should return specified model when valid model is provided", () => {
const testModelId: SyntheticModelId = "hf:zai-org/GLM-4.5"
const testModelId: SyntheticModelId = "hf:zai-org/GLM-4.6"
const handlerWithModel = new SyntheticHandler({
apiModelId: testModelId,
syntheticApiKey: "test-synthetic-api-key",
Expand All @@ -93,8 +103,8 @@ describe("SyntheticHandler", () => {
expect(model.info).toEqual(expect.objectContaining(syntheticModels[testModelId]))
})

it("should return GLM Instruct model with correct configuration", () => {
const testModelId: SyntheticModelId = "hf:zai-org/GLM-4.5"
it("should return GLM model with correct configuration", () => {
const testModelId: SyntheticModelId = "hf:zai-org/GLM-4.6"
const handlerWithModel = new SyntheticHandler({
apiModelId: testModelId,
syntheticApiKey: "test-synthetic-api-key",
Expand Down Expand Up @@ -175,7 +185,7 @@ describe("SyntheticHandler", () => {
})

it("createMessage should pass correct parameters to synthetic client", async () => {
const modelId: SyntheticModelId = "hf:zai-org/GLM-4.5"
const modelId: SyntheticModelId = "hf:zai-org/GLM-4.6"
const modelInfo = syntheticModels[modelId]
const handlerWithModel = new SyntheticHandler({
apiModelId: modelId,
Expand All @@ -201,7 +211,6 @@ describe("SyntheticHandler", () => {
expect(mockCreate).toHaveBeenCalledWith(
expect.objectContaining({
model: modelId,
max_tokens: 0.2 * modelInfo.maxTokens,
temperature: 0.5,
messages: expect.arrayContaining([{ role: "system", content: systemPrompt }]),
stream: true,
Expand Down
10 changes: 7 additions & 3 deletions src/api/providers/fetchers/modelCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { getIOIntelligenceModels } from "./io-intelligence"
import { getOvhCloudAiEndpointsModels } from "./ovhcloud"
import { getGeminiModels } from "./gemini"
import { getInceptionModels } from "./inception"
import { getSyntheticModels } from "./synthetic"
// kilocode_change end

import { getDeepInfraModels } from "./deepinfra"
Expand Down Expand Up @@ -107,6 +108,12 @@ export const getModels = async (options: GetModelsOptions): Promise<ModelRecord>
})
break
}
case "chutes":
models = await getChutesModels(options.apiKey)
break
case "synthetic":
models = await getSyntheticModels(options.apiKey)
break
case "gemini":
models = await getGeminiModels({
apiKey: options.apiKey,
Expand Down Expand Up @@ -147,9 +154,6 @@ export const getModels = async (options: GetModelsOptions): Promise<ModelRecord>
models = await getRooModels(rooBaseUrl, options.apiKey)
break
}
case "chutes":
models = await getChutesModels(options.apiKey)
break
default: {
// Ensures router is exhaustively checked if RouterName is a strict union.
const exhaustiveCheck: never = provider
Expand Down
Loading