chat
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Viewing readonly version of main branch: v126View latest version
┌─────────────────────────────────────────────────────────────────────┐
│ USER INPUT (Frontend) │
│ │
│ Model: qwen/qwen3-32b │
│ Parameters: │
│ - reasoningEffort: "medium" ← UI-friendly value │
│ - temperature: 0.7 │
│ - webSearch: true │
└───────────────────────────────┬─────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────────────────┐
│ JOBS API (backend/routes/jobs.ts) │
│ │
│ 1. Receive job request │
│ 2. Extract parameters from input │
│ 3. VALIDATE parameters │
│ ├─ validateParameters(modelId, params) │
│ ├─ Check required fields │
│ ├─ Check value ranges │
│ └─ Check allowed values (with apiMapping support) │
│ │
│ 4. TRANSFORM parameters │
│ └─ transformParametersForAPI(modelId, params) │
│ "medium" → "default" ✓ │
│ │
│ 5. Pass transformed params to provider │
└───────────────────────────────┬─────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────────────────┐
│ GROQ PROVIDER (backend/providers/groq.ts) │
│ │
│ 1. Receive chat options with transformed parameters │
│ 2. Build request body │
│ 3. Apply transformations again (double-check) │
│ └─ transformParametersForAPI(model, { reasoningEffort, ... }) │
│ 4. Only add parameters if model supports them │
│ └─ if (param && modelSupportsParameter(model, key)) │
│ 5. Send request to Groq API │
└───────────────────────────────┬─────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────────────────┐
│ GROQ API (External) │
│ │
│ POST https://api.groq.com/openai/v1/chat/completions │
│ { │
│ "model": "qwen/qwen3-32b", │
│ "messages": [...], │
│ "reasoning_effort": "default", ← API-compatible value ✓ │
│ "temperature": 0.7, │
│ "stream": true │
│ } │
│ │
│ ✓ Success! No more errors │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ MODEL CONFIG: qwen/qwen3-32b │
│ │
│ parameters: [ │
│ { │
│ key: 'reasoningEffort', │
│ type: 'select', │
│ options: [ │
│ { value: 'none', label: 'None' }, │
│ { value: 'default', label: 'Default' } │
│ ], │
│ apiMapping: { ← THE KEY FEATURE │
│ 'none': 'none', ✓ Direct mapping │
│ 'default': 'default', ✓ Direct mapping │
│ 'low': 'none', ✓ Backwards compat │
│ 'medium': 'default', ✓ Backwards compat │
│ 'high': 'default' ✓ Backwards compat │
│ } │
│ } │
│ ] │
└─────────────────────────────────────────────────────────────────────┘
validateParameters(modelId, params)
│
├─ For each parameter in model config:
│ │
│ ├─ Check if required and missing → ERROR
│ │
│ ├─ If present, validate by type:
│ │ │
│ │ ├─ NUMBER:
│ │ │ ├─ Is it a number?
│ │ │ ├─ Within min/max range?
│ │ │ └─ → Add to errors if invalid
│ │ │
│ │ ├─ SELECT:
│ │ │ ├─ Is it one of the allowed options?
│ │ │ ├─ OR is it a valid apiMapping key? ← NEW
│ │ │ └─ → Add to errors if invalid
│ │ │
│ │ ├─ STRING/TEXTAREA:
│ │ │ ├─ Within maxLength?
│ │ │ └─ → Add to errors if invalid
│ │ │
│ │ └─ BOOLEAN:
│ │ └─ Is it true/false?
│ │
│ └─ Continue to next parameter
│
└─ Return array of error messages (empty if valid)
transformParametersForAPI(modelId, params)
│
├─ Get model config
│
├─ For each parameter:
│ │
│ ├─ Is it a SELECT parameter?
│ │ │
│ │ ├─ Does it have apiMapping?
│ │ │ │
│ │ │ ├─ Is current value in mapping?
│ │ │ │ │
│ │ │ │ └─ YES: Replace value with mapped value
│ │ │ │ "medium" → "default" ✓
│ │ │ │
│ │ │ └─ NO: Keep original value
│ │ │
│ │ └─ No apiMapping: Keep original value
│ │
│ └─ Not a SELECT: Keep original value
│
├─ Apply model-specific transformParameters() if exists
│
└─ Return transformed parameters
User selects "medium" reasoning
↓
Sent directly to API
↓
Groq API rejects: "must be 'none' or 'default'"
↓
Error shown to user 😞
User selects "medium" reasoning
↓
Validated: "medium" is valid (in apiMapping) ✓
↓
Transformed: "medium" → "default"
↓
Sent to API with correct value
↓
API accepts request ✓
↓
User gets response 😊
SelectParameter.apiMapping: Maps UI values to API valuesvalidateParameters(): Validates before sending to APItransformParametersForAPI(): Transforms values using mappingsModelConfig.transformParameters: Custom transformation logic (optional)- Provider Integration: Uses transformations automatically
- ✅ Declarative: Define mappings in config, not scattered in code
- ✅ Type-Safe: TypeScript checks everything
- ✅ Backwards Compatible: Old values still work
- ✅ Extensible: Easy to add new models/mappings
- ✅ Debuggable: Clear validation errors
- ✅ No Code Duplication: One system for all providers
