diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e0df176..ce0dc18 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,7 +21,7 @@ The formal catalog convention is the [Model Parameters convention](docs/model-pa 3. **Required top-level fields:** `provider`, `authType` (`api_key` or `subscription`), `model`, `params`. 4. **Parameter shape:** each item in `params` has: - - `path` (required): snake_case, supports dot notation for nested fields (`thinking.type`). + - `path` (required): exact provider API request parameter path; supports dot notation for nested fields (`thinking.type`, `generationConfig.topK`). - `type` (required): one of `boolean`, `enum`, `integer`, `number`, `string`. - `label` (required): human-readable name (e.g. `"Max tokens"`). - `description` (required): one sentence, ≤500 chars. diff --git a/docs/model-parameters-schema.md b/docs/model-parameters-schema.md index 7352d8c..d3e5048 100644 --- a/docs/model-parameters-schema.md +++ b/docs/model-parameters-schema.md @@ -5,9 +5,10 @@ modelparams.dev to describe the request parameters available for a specific provider, auth type, and model. This catalog is metadata. It describes knobs a consumer can put into an outbound -model request, such as `temperature`, `top_p`, `max_tokens`, or -`thinking.type`. It does not describe API transport capabilities, proxy behavior, -authentication flows, endpoint compatibility, pricing, or UI control types. +model request, such as `temperature`, `top_p`, `max_tokens`, +`thinking.type`, or `generationConfig.topK`. It does not describe API transport +capabilities, proxy behavior, authentication flows, endpoint compatibility, +pricing, or UI control types. The public runtime sources are: @@ -49,7 +50,9 @@ Conventions: contain dots or colons when the upstream model id does. - `authType` is `api_key` or `subscription`. - `params` is the non-empty list of parameters for that exact route. -- `path` is a snake_case dot path into stored params and outbound request params. +- `path` is the exact provider API request parameter path in dot notation. Use + the provider's documented field casing, such as `top_p`, + `thinking.budget_tokens`, or `generationConfig.topK`. - `stream` is reserved for API-level streaming capability metadata and is not a valid MPS parameter path. - `type` is the semantic data type, not a UI control kind. @@ -115,7 +118,7 @@ This means: disable the parameter when `thinking.type` is `adaptive` or ## Match Values -Each match key is a snake_case dot path. Each match value uses one of: +Each match key is a provider API request parameter path. Each match value uses one of: - JSON primitive: string, number, boolean, or null - non-empty array of JSON primitives diff --git a/models/google/gemini-2.5-flash-lite.yaml b/models/google/gemini-2.5-flash-lite.yaml new file mode 100644 index 0000000..aeb3bf1 --- /dev/null +++ b/models/google/gemini-2.5-flash-lite.yaml @@ -0,0 +1,77 @@ +# yaml-language-server: $schema=https://modelparams.dev/api/v1/schema.json +provider: google +authType: api_key +model: gemini-2.5-flash-lite +params: + - path: generationConfig.maxOutputTokens + type: integer + label: Max output tokens + description: Maximum number of tokens to include in a response candidate. + range: + min: 1 + max: 65536 + group: generation_length + - path: generationConfig.temperature + type: number + label: Temperature + description: Controls randomness. Lower values make outputs more focused; higher values make them more varied. + default: 1 + range: + min: 0 + max: 2 + step: 0.1 + group: sampling + - path: generationConfig.topP + type: number + label: Top P + description: Controls nucleus sampling by limiting generation to tokens within the selected cumulative probability. + default: 0.95 + range: + min: 0 + max: 1 + step: 0.01 + group: sampling + - path: generationConfig.topK + type: integer + label: Top K + description: Limits token sampling to the top K most likely next tokens. + default: 64 + range: + min: 1 + group: sampling + - path: generationConfig.seed + type: integer + label: Seed + description: Optional seed used for decoding when reproducible sampling is desired. + group: sampling + - path: generationConfig.presencePenalty + type: number + label: Presence penalty + description: Penalizes tokens that have already appeared in the response to encourage new vocabulary. + group: sampling + - path: generationConfig.frequencyPenalty + type: number + label: Frequency penalty + description: Penalizes tokens proportionally to how often they have already appeared in the response. + group: sampling + - path: generationConfig.thinkingConfig.thinkingBudget + type: integer + label: Thinking budget + description: Number of thinking tokens Gemini should use; -1 uses dynamic thinking, 0 disables thinking, and fixed budgets start at 512 tokens. + default: 0 + group: reasoning + - path: generationConfig.thinkingConfig.includeThoughts + type: boolean + label: Include thoughts + description: Controls whether Gemini returns available thought summaries in the response parts. + default: false + group: reasoning + - path: generationConfig.responseMimeType + type: enum + label: Response MIME type + description: MIME type for generated text candidates. + default: text/plain + values: + - text/plain + - application/json + group: output_format diff --git a/models/google/gemini-2.5-flash.yaml b/models/google/gemini-2.5-flash.yaml new file mode 100644 index 0000000..bfe07ff --- /dev/null +++ b/models/google/gemini-2.5-flash.yaml @@ -0,0 +1,80 @@ +# yaml-language-server: $schema=https://modelparams.dev/api/v1/schema.json +provider: google +authType: api_key +model: gemini-2.5-flash +params: + - path: generationConfig.maxOutputTokens + type: integer + label: Max output tokens + description: Maximum number of tokens to include in a response candidate. + range: + min: 1 + max: 65536 + group: generation_length + - path: generationConfig.temperature + type: number + label: Temperature + description: Controls randomness. Lower values make outputs more focused; higher values make them more varied. + default: 1 + range: + min: 0 + max: 2 + step: 0.1 + group: sampling + - path: generationConfig.topP + type: number + label: Top P + description: Controls nucleus sampling by limiting generation to tokens within the selected cumulative probability. + default: 0.95 + range: + min: 0 + max: 1 + step: 0.01 + group: sampling + - path: generationConfig.topK + type: integer + label: Top K + description: Limits token sampling to the top K most likely next tokens. + default: 64 + range: + min: 1 + group: sampling + - path: generationConfig.seed + type: integer + label: Seed + description: Optional seed used for decoding when reproducible sampling is desired. + group: sampling + - path: generationConfig.presencePenalty + type: number + label: Presence penalty + description: Penalizes tokens that have already appeared in the response to encourage new vocabulary. + group: sampling + - path: generationConfig.frequencyPenalty + type: number + label: Frequency penalty + description: Penalizes tokens proportionally to how often they have already appeared in the response. + group: sampling + - path: generationConfig.thinkingConfig.thinkingBudget + type: integer + label: Thinking budget + description: Number of thinking tokens Gemini should use; 0 disables thinking and -1 uses dynamic thinking. + default: -1 + range: + min: -1 + max: 24576 + group: reasoning + - path: generationConfig.thinkingConfig.includeThoughts + type: boolean + label: Include thoughts + description: Controls whether Gemini returns available thought summaries in the response parts. + default: false + group: reasoning + - path: generationConfig.responseMimeType + type: enum + label: Response MIME type + description: MIME type for generated text candidates. + default: text/plain + values: + - text/plain + - application/json + group: output_format diff --git a/models/google/gemini-2.5-pro.yaml b/models/google/gemini-2.5-pro.yaml new file mode 100644 index 0000000..d7660d8 --- /dev/null +++ b/models/google/gemini-2.5-pro.yaml @@ -0,0 +1,79 @@ +# yaml-language-server: $schema=https://modelparams.dev/api/v1/schema.json +provider: google +authType: api_key +model: gemini-2.5-pro +params: + - path: generationConfig.maxOutputTokens + type: integer + label: Max output tokens + description: Maximum number of tokens to include in a response candidate. + range: + min: 1 + max: 65536 + group: generation_length + - path: generationConfig.temperature + type: number + label: Temperature + description: Controls randomness. Lower values make outputs more focused; higher values make them more varied. + default: 1 + range: + min: 0 + max: 2 + step: 0.1 + group: sampling + - path: generationConfig.topP + type: number + label: Top P + description: Controls nucleus sampling by limiting generation to tokens within the selected cumulative probability. + default: 0.95 + range: + min: 0 + max: 1 + step: 0.01 + group: sampling + - path: generationConfig.topK + type: integer + label: Top K + description: Limits token sampling to the top K most likely next tokens. + default: 64 + range: + min: 1 + group: sampling + - path: generationConfig.seed + type: integer + label: Seed + description: Optional seed used for decoding when reproducible sampling is desired. + group: sampling + - path: generationConfig.presencePenalty + type: number + label: Presence penalty + description: Penalizes tokens that have already appeared in the response to encourage new vocabulary. + group: sampling + - path: generationConfig.frequencyPenalty + type: number + label: Frequency penalty + description: Penalizes tokens proportionally to how often they have already appeared in the response. + group: sampling + - path: generationConfig.thinkingConfig.thinkingBudget + type: integer + label: Thinking budget + description: Maximum number of thinking tokens Gemini should use before producing the final answer. + range: + min: 128 + max: 32768 + group: reasoning + - path: generationConfig.thinkingConfig.includeThoughts + type: boolean + label: Include thoughts + description: Controls whether Gemini returns available thought summaries in the response parts. + default: false + group: reasoning + - path: generationConfig.responseMimeType + type: enum + label: Response MIME type + description: MIME type for generated text candidates. + default: text/plain + values: + - text/plain + - application/json + group: output_format diff --git a/models/google/gemini-3.5-flash.yaml b/models/google/gemini-3.5-flash.yaml new file mode 100644 index 0000000..27fa32a --- /dev/null +++ b/models/google/gemini-3.5-flash.yaml @@ -0,0 +1,82 @@ +# yaml-language-server: $schema=https://modelparams.dev/api/v1/schema.json +provider: google +authType: api_key +model: gemini-3.5-flash +params: + - path: generationConfig.maxOutputTokens + type: integer + label: Max output tokens + description: Maximum number of tokens to include in a response candidate. + range: + min: 1 + max: 65536 + group: generation_length + - path: generationConfig.temperature + type: number + label: Temperature + description: Controls randomness. Lower values make outputs more focused; higher values make them more varied. + default: 1 + range: + min: 0 + max: 2 + step: 0.1 + group: sampling + - path: generationConfig.topP + type: number + label: Top P + description: Controls nucleus sampling by limiting generation to tokens within the selected cumulative probability. + default: 0.95 + range: + min: 0 + max: 1 + step: 0.01 + group: sampling + - path: generationConfig.topK + type: integer + label: Top K + description: Limits token sampling to the top K most likely next tokens. + default: 64 + range: + min: 1 + group: sampling + - path: generationConfig.seed + type: integer + label: Seed + description: Optional seed used for decoding when reproducible sampling is desired. + group: sampling + - path: generationConfig.presencePenalty + type: number + label: Presence penalty + description: Penalizes tokens that have already appeared in the response to encourage new vocabulary. + group: sampling + - path: generationConfig.frequencyPenalty + type: number + label: Frequency penalty + description: Penalizes tokens proportionally to how often they have already appeared in the response. + group: sampling + - path: generationConfig.thinkingConfig.thinkingLevel + type: enum + label: Thinking level + description: Controls Gemini 3.5 Flash reasoning effort. + default: medium + values: + - minimal + - low + - medium + - high + group: reasoning + - path: generationConfig.thinkingConfig.includeThoughts + type: boolean + label: Include thoughts + description: Controls whether Gemini returns available thought summaries in the response parts. + default: false + group: reasoning + - path: generationConfig.responseMimeType + type: enum + label: Response MIME type + description: MIME type for generated text candidates. + default: text/plain + values: + - text/plain + - application/json + group: output_format diff --git a/src/schema/model.ts b/src/schema/model.ts index 1203127..731d363 100644 --- a/src/schema/model.ts +++ b/src/schema/model.ts @@ -19,7 +19,7 @@ export type ParameterGroup = z.infer; const PROVIDER_SLUG = /^[a-z0-9][a-z0-9-]*$/; const MODEL_ID = /^[a-z0-9][a-z0-9._:-]*$/; -const PARAM_PATH = /^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*$/; +const PARAM_PATH = /^[A-Za-z][A-Za-z0-9_]*(\.[A-Za-z][A-Za-z0-9_]*)*$/; const BLOCKED_PARAM_PATHS = new Set(["stream"]); export const Range = z @@ -48,7 +48,7 @@ const ApplicabilityValue = z.union([JsonPrimitive, JsonPrimitiveArray, Applicabi export const ApplicabilityRule = z .record( - z.string().regex(PARAM_PATH, "applicability keys must be snake_case dot paths"), + z.string().regex(PARAM_PATH, "applicability keys must be provider API dot paths"), ApplicabilityValue, ) .refine((rule) => Object.keys(rule).length > 0, { @@ -73,7 +73,7 @@ const baseParameterShape = { path: z .string() .min(1) - .regex(PARAM_PATH, "param path must be snake_case dot-notation (e.g. `thinking.type`)"), + .regex(PARAM_PATH, "param path must be a provider API dot path (e.g. `thinking.type`)"), label: z.string().min(1).max(80), description: z.string().min(1).max(500), group: ParameterGroup, diff --git a/tests/schema.test.ts b/tests/schema.test.ts index a197833..54947c9 100644 --- a/tests/schema.test.ts +++ b/tests/schema.test.ts @@ -99,6 +99,25 @@ describe("Model schema", () => { expect(result.success).toBe(false); }); + it("accepts provider API paths with native casing", () => { + const result = Model.safeParse({ + ...VALID_MODEL, + provider: "google", + model: "gemini-3.5-flash", + params: [ + { + path: "generationConfig.thinkingConfig.thinkingLevel", + type: "enum", + label: "Thinking level", + description: "x", + values: ["low", "medium", "high"], + group: "reasoning", + }, + ], + }); + expect(result.success).toBe(true); + }); + it("rejects bad param path", () => { const result = Model.safeParse({ ...VALID_MODEL, @@ -180,6 +199,27 @@ describe("Model schema", () => { expect(result.success).toBe(true); }); + it("accepts provider API paths in applicability rules", () => { + const result = Model.safeParse({ + ...VALID_MODEL, + provider: "google", + model: "gemini-3.5-flash", + params: [ + { + path: "generationConfig.thinkingConfig.includeThoughts", + type: "boolean", + label: "Include thoughts", + description: "x", + group: "reasoning", + applicability: { + except: { "generationConfig.thinkingConfig.thinkingLevel": "minimal" }, + }, + }, + ], + }); + expect(result.success).toBe(true); + }); + it("rejects unknown applicability operators", () => { const result = Model.safeParse({ ...VALID_MODEL,