Plugin Configuration: config_schema
Plugin configuration lets administrators provide API keys, endpoints, model names, switches, enum options, or numeric parameters, then injects them into the runtime through Ting.config.
Plugin Configuration: config_schema
When a plugin needs administrator-provided API keys, endpoints, model names, switches, enum options, or numeric parameters, declare config_schema in plugin.yml. Ting Reader uses it to render the plugin settings form, extract defaults, store configuration, validate values, encrypt sensitive fields, and inject decrypted values into Ting.config at runtime.
config_schema:
type: object
properties:
api_base_url:
type: string
title:
zh: API 地址
en: API endpoint
description:
zh: OpenAI 兼容接口地址,可以填写服务根地址或完整 /v1/chat/completions 地址。
en: OpenAI-compatible endpoint. A service root or full /v1/chat/completions URL is accepted.
placeholder:
zh: https://api.example.com/v1/chat/completions
en: https://api.example.com/v1/chat/completions
default: https://api.openai.com/v1/chat/completions
api_key:
type: string
format: secret
x-encrypted: true
title:
zh: API 密钥
en: API key
description:
zh: 后端会加密保存,插件运行时通过 Ting.config.api_key 读取明文值。
en: Stored encrypted by the backend. The plugin reads the plaintext value from Ting.config.api_key at runtime.
model:
type: string
title:
zh: 模型
en: Model
default: gpt-4.1-mini
mode:
type: string
title:
zh: 处理模式
en: Processing mode
default: balanced
enum:
- fast
- balanced
- accurate
enum_labels:
fast:
zh: 快速
en: Fast
balanced:
zh: 平衡
en: Balanced
accurate:
zh: 准确
en: Accurate
temperature:
type: number
title:
zh: 温度
en: Temperature
default: 0.2
minimum: 0
maximum: 1
max_candidates:
type: integer
title:
zh: 最大候选数
en: Max candidates
default: 8
minimum: 1
maximum: 20
enabled:
type: boolean
title:
zh: 启用增强处理
en: Enable enhanced processing
default: trueThe backend also accepts a flat shorthand and normalizes it to type: object with properties. This is convenient for simple plugins:
config_schema:
api_key:
type: string
format: secret
x-encrypted: true
title: API Key
source_url:
type: string
title: Source URL
default: https://example.com/plugins.json| schema | Admin form |
|---|---|
| type: string | Text input |
| type: string + enum | Select dropdown |
| type: number | Number input |
| type: integer | Number input saved as a number |
| type: boolean | Checkbox |
| format: password / format: secret | Password input and sensitive-field handling |
| x-encrypted: true / encrypted: true | Password input and encrypted storage |
title, description, and placeholder can be plain strings or localized objects. enum_labels can provide localized display labels for enum values. For secrets, prefer using both format: secret and x-encrypted: true.
The backend encrypts a field when it sees x-encrypted: true, encrypted: true, format: password, or format: secret. The plugin settings dialog does not echo plaintext secrets back to the browser. If the user keeps an existing secret unchanged, the frontend sends an internal placeholder and the backend preserves the stored value; plugin authors do not need to handle that placeholder.
function readConfig() {
const config = Ting.config || {};
return {
apiBaseUrl: String(config.api_base_url || "https://api.openai.com/v1/chat/completions"),
apiKey: String(config.api_key || ""),
model: String(config.model || "gpt-4.1-mini"),
enabled: config.enabled !== false,
maxCandidates: Number(config.max_candidates || 8),
};
}
async function search(args) {
const config = readConfig();
if (!config.apiKey) {
Ting.log?.warn?.("api_key is empty; returning fallback result.");
}
}
globalThis.search = search;The plugin management page reads and saves configuration through these endpoints. Saving validates the schema, encrypts sensitive fields, and notifies the plugin manager. When debugging configuration changes, save first and then reload the plugin.
GET /api/v1/plugins/:id/config
PUT /api/v1/plugins/:id/config
Content-Type: application/json
{
"config": {
"api_key": "sk-...",
"model": "gpt-4.1-mini",
"enabled": true
}
}config_schemais for the plugin's own configuration, not a libraryscraper_config.defaultinitializes and fills missing fields; it does not overwrite values the user already saved.- Do not print API keys in logs or descriptions.
- The current settings dialog does not render nested objects, arrays, or complex forms. Split complex settings into simple fields, or provide a custom configuration panel with
ui_extension. - After changing
config_schemainplugin.yml, rebuild/reinstall or reload the plugin so the admin page sees the new form.