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: true

The 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
schemaAdmin form
type: stringText input
type: string + enumSelect dropdown
type: numberNumber input
type: integerNumber input saved as a number
type: booleanCheckbox
format: password / format: secretPassword input and sensitive-field handling
x-encrypted: true / encrypted: truePassword 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_schema is for the plugin's own configuration, not a library scraper_config.
  • default initializes 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_schema in plugin.yml, rebuild/reinstall or reload the plugin so the admin page sees the new form.