mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
feat(vscode): propagate isFree from cloud API through CLI to extension
Add isFree field to the full model data pipeline: gateway schema, ModelsDev.Model, Provider.Model, OpenAPI spec, and SDK types. Remove cost-based isFree fallback in the extension model selector — rely solely on the backend-provided value.
This commit is contained in:
@@ -30,6 +30,7 @@ const openRouterModelSchema = z.object({
|
||||
top_provider: z.object({ max_completion_tokens: z.number().nullish() }).optional(),
|
||||
supported_parameters: z.array(z.string()).optional(),
|
||||
preferredIndex: z.number().optional(),
|
||||
isFree: z.boolean().optional(),
|
||||
opencode: z
|
||||
.object({
|
||||
family: z.string().optional(),
|
||||
@@ -162,6 +163,7 @@ function transformToModelDevFormat(model: OpenRouterModel): any {
|
||||
variants: model.opencode?.variants,
|
||||
prompt: model.opencode?.prompt,
|
||||
tool_call: supportsTools,
|
||||
isFree: model.isFree,
|
||||
...(inputPrice !== undefined &&
|
||||
outputPrice !== undefined && {
|
||||
cost: {
|
||||
|
||||
@@ -10,12 +10,8 @@ export function providerSortKey(providerID: string, order = PROVIDER_ORDER): num
|
||||
return idx >= 0 ? idx : order.length
|
||||
}
|
||||
|
||||
export function isFree(model: Pick<EnrichedModel, "isFree" | "cost" | "providerID">): boolean {
|
||||
if (model.isFree !== undefined) return model.isFree
|
||||
// TODO: temporary — this logic will be moved to the backend
|
||||
if (model.providerID !== KILO_GATEWAY_ID) return false
|
||||
// TODO: fallback to cost check — delete once backend ships isFree attribute
|
||||
return model.cost?.input === 0 && model.cost?.output === 0
|
||||
export function isFree(model: Pick<EnrichedModel, "isFree">): boolean {
|
||||
return model.isFree === true
|
||||
}
|
||||
|
||||
export function stripSubProviderPrefix(name: string): string {
|
||||
|
||||
@@ -86,6 +86,7 @@ export namespace ModelsDev {
|
||||
// kilocode_change start
|
||||
recommendedIndex: z.number().optional(),
|
||||
prompt: Prompt.optional().catch(undefined),
|
||||
isFree: z.boolean().optional(),
|
||||
// kilocode_change end
|
||||
|
||||
experimental: z.boolean().optional(),
|
||||
|
||||
@@ -689,6 +689,7 @@ export namespace Provider {
|
||||
// kilocode_change start
|
||||
recommendedIndex: z.number().optional(),
|
||||
prompt: Prompt.optional().catch(undefined),
|
||||
isFree: z.boolean().optional(),
|
||||
// kilocode_change end
|
||||
})
|
||||
.meta({
|
||||
@@ -775,6 +776,7 @@ export namespace Provider {
|
||||
variants: provider.id === "kilo" ? (model.variants ?? {}) : {},
|
||||
recommendedIndex: model.recommendedIndex,
|
||||
prompt: model.prompt,
|
||||
isFree: model.isFree,
|
||||
// kilocode_change end
|
||||
}
|
||||
|
||||
@@ -923,6 +925,7 @@ export namespace Provider {
|
||||
// kilocode_change start
|
||||
recommendedIndex: model.recommendedIndex ?? existingModel?.recommendedIndex,
|
||||
prompt: model.prompt ?? existingModel?.prompt,
|
||||
isFree: model.isFree ?? existingModel?.isFree,
|
||||
// kilocode_change end
|
||||
}
|
||||
const merged = mergeDeep(ProviderTransform.variants(parsedModel), model.variants ?? {})
|
||||
|
||||
@@ -1214,6 +1214,7 @@ export type ProviderConfig = {
|
||||
}
|
||||
recommendedIndex?: number
|
||||
prompt?: "codex" | "gemini" | "beast" | "anthropic" | "trinity" | "anthropic_without_todo"
|
||||
isFree?: boolean
|
||||
experimental?: boolean
|
||||
status?: "alpha" | "beta" | "deprecated"
|
||||
options?: {
|
||||
@@ -1646,6 +1647,7 @@ export type Model = {
|
||||
}
|
||||
recommendedIndex?: number
|
||||
prompt?: "codex" | "gemini" | "beast" | "anthropic" | "trinity" | "anthropic_without_todo"
|
||||
isFree?: boolean
|
||||
}
|
||||
|
||||
export type Provider = {
|
||||
@@ -4159,6 +4161,7 @@ export type ProviderListResponses = {
|
||||
}
|
||||
recommendedIndex?: number
|
||||
prompt?: "codex" | "gemini" | "beast" | "anthropic" | "trinity" | "anthropic_without_todo"
|
||||
isFree?: boolean
|
||||
experimental?: boolean
|
||||
status?: "alpha" | "beta" | "deprecated"
|
||||
options: {
|
||||
|
||||
@@ -4838,6 +4838,9 @@
|
||||
"type": "string",
|
||||
"enum": ["codex", "gemini", "beast", "anthropic", "trinity", "anthropic_without_todo"]
|
||||
},
|
||||
"isFree": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"experimental": {
|
||||
"type": "boolean"
|
||||
},
|
||||
@@ -11403,6 +11406,9 @@
|
||||
"type": "string",
|
||||
"enum": ["codex", "gemini", "beast", "anthropic", "trinity", "anthropic_without_todo"]
|
||||
},
|
||||
"isFree": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"experimental": {
|
||||
"type": "boolean"
|
||||
},
|
||||
@@ -12373,6 +12379,9 @@
|
||||
"prompt": {
|
||||
"type": "string",
|
||||
"enum": ["codex", "gemini", "beast", "anthropic", "trinity", "anthropic_without_todo"]
|
||||
},
|
||||
"isFree": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
Reference in New Issue
Block a user