Admin guide
Channel management
Channels are the core configuration unit that connects the platform to AI providers
Each channel holds one upstream provider's API key and connection settings. After signing in as an admin, open it from the left sidebar under “Admin area → Channel management”, or go directly to `/console/channel`. The list can be searched by ID, name, key, API address, and model keyword. The web console page follows the reference design and is still being wired up.
| ID | Name | Group | Type | Status | Response time | Priority | Actions | |
|---|---|---|---|---|---|---|---|---|
| ☐ | 1 | OpenAI default | default | OpenAI | Enabled | 128 ms | 10 | Test · Disable · Edit · ··· |
| ☐ | 2 | Azure backup | prod | Azure | Disabled | — | 5 | Test · Enable · Edit · ··· |
Channel list preview: tag tabs, filter bar, and inline test and enable/disable actions
Add a channel
Basic settings
Click “Add channel” to open the form, then fill in the basic information needed to connect to the upstream provider:
| Field | Description |
|---|---|
name · Channel name | Name it by provider and purpose, for example “OpenAI production” |
type · Channel type | Determines the request adapter and the default Base URL |
key · API Key | Upstream key; supports a single key or multiple keys (see Multi-key mode) |
base_url · Base URL | Custom proxy or compatible gateway address; leave empty to use the type's default |
group · Group | Defaults to default; matched against token groups and the ability table |
priority · Priority | Order of preference when a model is routed across multiple channels |
weight · Weight | Load-balancing weight, used together with rotation modes |
tag · Tag | Grouping label for bulk enable/disable and bulk editing |
Select models
- Select the models this channel can forward, or click “Fetch from upstream” to call
POST /api/channel/fetch_models - Fetch models for a specific channel:
GET /api/channel/fetch_models/{id} - Selected models are written to the
modelsfield; together with the ability table in “Model management”, they determine routing
Advanced settings
| Field | Description |
|---|---|
model_mapping · Model mapping | JSON that maps platform model names to upstream model names |
status_code_mapping · Status code mapping | Maps upstream HTTP status codes to unified errors |
test_model · Test model | Model ID used for connectivity tests |
auto_ban · Auto-disable | Automatically disables the channel after repeated failures |
header_override · Header override | Adds or replaces HTTP headers forwarded to the upstream |
remark · Remark | Notes visible only to admins |
Submit and save
- Create:
POST /api/channel/ - Update:
PUT /api/channel/ - Duplicate an existing channel:
POST /api/channel/{id}/copy - After saving, you return to the list; Root users can view the full key via
POST /api/channel/{id}/key
Channel testing
Test a single channel
Click “Test” in the row, or call POST /api/channel/{id}/test. The system sends a probe using the channel's configured test_model and, on success, updates response_time and test_time.
Test in bulk
“Test all channels” in the toolbar maps to GET /api/channel/test and checks every enabled channel in turn. You can also call GET /api/channel/update_balance to refresh balances in bulk.
Bulk actions
Select channels
Tick the checkboxes on the left side of the list. Use the tag tabs at the top to show channels that share a tag, or use the search box to filter by ID, name, key, Base URL, or model keyword (GET /api/channels?keyword=).
Run bulk actions
| Action | API | Description |
|---|---|---|
| Delete selected | POST /api/channel/batch | Deletes the selected channels (cannot be undone) |
| Enable by tag | POST /api/channel/tag/enabled | Enables all channels under the same tag |
| Disable by tag | POST /api/channel/tag/disabled | Disables all channels under the same tag |
| Set tag in bulk | POST /api/channel/batch/tag | Applies the same tag to all selected channels |
| Delete disabled | DELETE /api/channel/disabled | Removes all disabled channels |
Multi-key mode
Configure multiple keys
Turn on “Multi-key” in the channel edit form and enter one upstream key per line, or maintain keys in bulk via POST /api/channel/multi_key/manage. This is useful for rotating across several accounts at the same provider to raise quota limits.
Choose a rotation mode
| Mode | Description |
|---|---|
random · Random | Picks a random available key for each request |
round_robin · Round robin | Cycles through the keys in order |
priority · Priority | Uses higher-priority keys first and falls back on failure |
Save the configuration
Once saved, the gateway distributes requests across the keys using the selected mode. When a single key keeps failing, auto_ban can automatically disable that key or the entire channel.
Parameter override system
Simple override mode
Enter a JSON object in param_override, where each key is a dot-separated path (such as temperature or max_tokens) and each value is what gets written into the request body. This works well for rewriting a few parameters with fixed values.
Advanced operations mode
Use the operations array to define complex parameter operations, including conditions, array operations, string concatenation, and normalization. It can be combined with header_override to handle unusual upstream formats.
Basic structure
{
"operations": [
{
"path": "temperature",
"mode": "set",
"value": 0.8,
"conditions": [...],
"logic": "AND"
}
]
}| Field | Description |
|---|---|
mode | Required. The operation type |
path | Used by set / delete / append / prepend / trim_* / ensure_* / trim_space / to_lower / to_upper / replace / regex_replace |
value | Commonly used by set / append / prepend / trim_prefix / trim_suffix / ensure_prefix / ensure_suffix |
from / to | Used by move / copy / replace / regex_replace |
keep_origin | For set, skips when a value already exists; used by append / prepend when merging objects |
conditions | Array of conditions; the operation runs only when they are met |
logic | AND (all must match) or OR (any one matches, default) |
Operation modes (mode)
- set - Set a value: Sets the value at the given path; with `keep_origin: true`, existing values are left unchanged
- delete - Delete a field: Removes the field at the given path from the request body
- move - Move a field: Moves the value at the `from` path to the `to` path
- append - Append content: Appends to the end of a string or array, or merges object properties
{ "path": "messages.0.content", "mode": "append", "value": "\n\nPlease answer in English." } - prepend - Prepend content: Inserts at the start of a string or array, or merges object properties
- copy - Copy a field: Copies the value from `from` to `to` without removing the source field
- trim_prefix - Remove a prefix: Removes the given prefix from a string; unchanged if it doesn't match
- trim_suffix - Remove a suffix: Removes the given suffix from a string; unchanged if it doesn't match
- ensure_prefix - Ensure a prefix: Makes sure the string starts with the given prefix
- ensure_suffix - Ensure a suffix: Makes sure the string ends with the given suffix
- trim_space - Trim whitespace: Runs TrimSpace on the string
- to_lower - Convert to lowercase: Converts a string field to lowercase
- to_upper - Convert to uppercase: Converts a string field to uppercase
- replace - Replace text: Substring replacement; `from` is required and `to` is optional
- regex_replace - Regex replace: Regex match and replace using Go regexp syntax
{ "path": "model", "mode": "regex_replace", "from": "^gpt-", "to": "openai/gpt-" }
Conditions
Use the conditions array to set when an operation runs; the operation is applied only when its conditions are met.
Condition structure
{
"conditions": [
{
"path": "model",
"mode": "contains",
"value": "gpt-4",
"invert": false,
"pass_missing_key": false
}
],
"logic": "AND"
}Condition match modes
full: exact match (default)prefix: prefix matchsuffix: suffix matchcontains: substring matchgt / gte / lt / lte: numeric comparison, for number values only
Numeric comparisons only work on number values; string operations (prefix, suffix, contains) convert the value to a string before comparing.
Condition parameters
invert: when true, inverts the match resultpass_missing_key: when the path doesn't exist: true counts as a pass, false as a fail (default)
Logic (logic)
AND: all conditions must be metOR: any one condition is enough (default)
Path syntax
Use JSON paths to access nested fields:
| Path | Description |
|---|---|
temperature | Top-level field |
messages.0.content | The content of the first array element |
messages.-1.content | The content of the last array element |
metadata.user.name | Nested object field |
Built-in variables (they don't need to exist in the request body and can be used directly in conditions):
| Variable | Description |
|---|---|
model / upstream_model | Target model after redirection, used for condition matching |
original_model | Model in the user's request before redirection |
Practical examples
1. Adjust model parameters dynamically
Set a different temperature depending on keywords in the message
{
"operations": [
{
"path": "temperature",
"mode": "set",
"value": 0.3,
"conditions": [{ "path": "messages.0.content", "mode": "contains", "value": "code" }]
},
{
"path": "temperature",
"mode": "set",
"value": 0.9,
"conditions": [{ "path": "messages.0.content", "mode": "contains", "value": "creative" }]
}
]
}2. Add a system prompt
Prepend a system message to the start of the messages array
{
"operations": [
{
"path": "messages",
"mode": "prepend",
"value": [{ "role": "system", "content": "You are a professional AI assistant. Always remain polite and professional." }]
}
]
}3. Adjust parameters by model type
Set a different max_tokens based on the model prefix
{
"operations": [
{
"path": "max_tokens",
"mode": "set",
"value": 4000,
"conditions": [{ "path": "model", "mode": "prefix", "value": "gpt-4" }]
},
{
"path": "max_tokens",
"mode": "set",
"value": 2000,
"conditions": [{ "path": "model", "mode": "prefix", "value": "gpt-3.5" }]
}
]
}4. Combine multiple conditions (AND logic)
Run the operation only when several conditions are all met
{
"operations": [
{
"path": "stream",
"mode": "set",
"value": false,
"conditions": [
{ "path": "model", "mode": "contains", "value": "claude" },
{ "path": "messages.0.content", "mode": "contains", "value": "long-form" }
],
"logic": "AND"
}
]
}5. Numeric comparison condition
Apply a condition based on a numeric value
{
"operations": [
{
"path": "temperature",
"mode": "set",
"value": 0.1,
"conditions": [
{ "path": "max_tokens", "mode": "gt", "value": 1000 }
]
}
]
}6. Inverted condition
Use invert to negate a condition
{
"operations": [
{
"path": "stream",
"mode": "set",
"value": true,
"conditions": [
{
"path": "model",
"mode": "contains",
"value": "gpt-3.5",
"invert": true
}
]
}
]
}7. Handle missing fields
Use pass_missing_key to handle fields that may not exist
{
"operations": [
{
"path": "temperature",
"mode": "set",
"value": 0.7,
"conditions": [
{
"path": "custom_field",
"mode": "full",
"value": "special",
"pass_missing_key": true
}
]
}
]
}8. String concatenation example
Append an instruction to the user's message
{
"operations": [
{
"path": "messages.-1.content",
"mode": "append",
"value": "\n\nPlease explain your reasoning in detail."
}
]
}Notes
- Operations run in the order of the operations array; earlier operations affect later ones
- Parameter overrides are intended only for legitimate upstream API compatibility, corporate network compatibility, and request normalization
- Numeric comparison conditions only apply to number values; string operations compare as strings
List columns
| Column | Field | Description |
|---|---|---|
| ID | id | Unique channel identifier |
| Name | name | A recognizable channel name |
| Group | group | Works together with token groups and the ability table |
| Type | type | Integration type, such as OpenAI, Azure, or Anthropic |
| Status | status | Enabled / Disabled; can be toggled quickly |
| Response time | response_time | Duration of the most recent connectivity test (ms) |
| Used/Remaining | used_quota / balance | Overview of the channel's quota or balance |
| Priority | priority | Scheduling priority within the same group; higher values are preferred |
The admin sidebar entry can be turned on under Profile settings → sidebar modules by enabling sidebar_modules.admin.channel. To troubleshoot routing failures, see Group management and Model management.