Different AI models/providers have incompatible parameter requirements, causing a "whack-a-mole" issue where:
- Qwen3-32B: Requires
reasoning_effortto be'none'or'default' - OpenAI o1/o3: Accepts
'low','medium','high' - GPT-OSS models: Don't support
image_detailat all - Vision models: Support
image_detailparameter - Other models: Don't support
reasoning_effortat all
This caused API errors like:
`reasoning_effort` must be one of `none` or `default`
property 'image_detail' is unsupported
Added apiMapping to SelectParameter type for value translation:
export interface SelectParameter extends BaseParameter {
type: 'select';
options: Array<{ value: string; label: string }>;
default?: string;
apiMapping?: Record<string, string>; // NEW: Maps UI → API values
}
Added transformParameters function to ModelConfig:
export interface ModelConfig {
// ... existing fields ...
transformParameters?: (params: Record<string, unknown>) => Record<string, unknown>;
}
Created transformParametersForAPI() that:
- Applies
apiMappingfor select parameters - Runs model-specific transformation functions
- Preserves unknown/unsupported parameters
transformParametersForAPI('qwen/qwen3-32b', {
reasoningEffort: 'medium', // UI value
temperature: 0.7
});
// Returns: { reasoningEffort: 'default', temperature: 0.7 }
Created validateParameters() that:
- Checks required parameters
- Validates number ranges (min/max)
- Validates select options (with apiMapping support)
- Validates string/textarea lengths
- Validates boolean types
Returns array of human-readable error messages.
Updated groq.ts provider:
- Imports
transformParametersForAPI - Transforms parameters before building request body
- Applied to both
complete()andstream()methods
const transformedParams = transformParametersForAPI(model, {
reasoningEffort: options?.reasoningEffort,
imageDetail: options?.imageDetail,
webSearch: options?.webSearch,
codeExecution: options?.codeExecution,
});
if (transformedParams.reasoningEffort && modelSupportsParameter(model, 'reasoningEffort')) {
requestBody.reasoning_effort = transformedParams.reasoningEffort;
}
Updated jobs.ts to validate and transform parameters:
- Validates parameters before starting job
- Transforms parameters for model-specific requirements
- Returns clear error messages on validation failure
// Validate parameters
const validationErrors = validateParameters(model, paramsToValidate);
if (validationErrors.length > 0) {
failJob(job, "Invalid parameters: " + validationErrors.join(", "));
return;
}
// Transform parameters
const transformedParams = transformParametersForAPI(model, paramsToValidate);
Updated qwen/qwen3-32b model config with proper parameter mapping:
{
id: 'qwen/qwen3-32b',
name: 'Qwen3-32B',
provider: 'groq',
parameters: [
// ... base parameters ...
{
key: 'reasoningEffort',
label: 'Reasoning Effort',
type: 'select',
options: [
{ value: 'none', label: 'None' },
{ value: 'default', label: 'Default' }
],
default: 'default',
apiMapping: {
'none': 'none',
'default': 'default',
// Backwards compatibility
'low': 'none',
'medium': 'default',
'high': 'default'
}
},
// ... other parameters ...
],
capabilities: { thinking: true, streaming: true }
}
-
backend/providers/model-configs.ts
- Added
apiMappingtoSelectParameter - Added
transformParameterstoModelConfig - Added
transformParametersForAPI()function - Added
validateParameters()function - Updated Qwen model config with proper parameters
- Added
-
backend/providers/groq.ts
- Import
transformParametersForAPI - Apply transformation in
complete()method - Apply transformation in
stream()method
- Import
-
backend/routes/jobs.ts
- Import validation and transformation functions
- Validate parameters before job execution
- Transform parameters before passing to provider
- Return validation errors to client
-
backend/providers/PARAMETER-VALIDATION.md
- Complete documentation of the system
- Usage examples
- Migration guide
- Common patterns
-
backend/providers/test-parameter-validation.ts
- Test suite demonstrating all features
- Validation examples
- Transformation examples
- Run with:
deno run backend/providers/test-parameter-validation.ts
Run the test suite:
cd /Users/janzheng/localhost/smallweb/design/v2/frontend/apps/chat-app deno run backend/providers/test-parameter-validation.ts
Expected output:
- ✅ Parameter transformation works (medium → default)
- ✅ Validation catches invalid values
- ✅ Backwards compatibility maintained
- ✅ Range validation works
- ✅ All valid parameters pass validation
- Single Source of Truth: Model requirements defined once in config
- Backwards Compatible: Old parameter values automatically mapped
- Type Safe: TypeScript validates at compile time
- Clear Errors: Meaningful error messages for invalid parameters
- Extensible: Easy to add new models with custom requirements
- No Code Changes: Providers automatically use transformations
- No Whack-a-Mole: Model-specific quirks handled declaratively
To add parameter mapping for other models:
- Identify models with parameter requirements (check API docs)
- Add
apiMappingto relevant parameters inmodel-configs.ts - Test with
test-parameter-validation.ts - Deploy - existing code automatically uses mappings
{
id: 'new-model',
name: 'New Model',
provider: 'custom',
parameters: [
{
key: 'creativityLevel',
label: 'Creativity',
type: 'select',
options: [
{ value: 'conservative', label: 'Conservative' },
{ value: 'balanced', label: 'Balanced' },
{ value: 'experimental', label: 'Experimental' }
],
default: 'balanced',
// Map UI values to what API expects
apiMapping: {
'conservative': '1',
'balanced': '2',
'experimental': '3'
}
}
]
}
No other code changes needed - transformation happens automatically!
