Files
scriptorium/docs/config.md

9.5 KiB

Configuration Reference

Config Discovery And Precedence

Application settings are loaded in this order:

  1. Built-in defaults
  2. config.yml values
  3. CLI overrides

When --config is not provided, Scriptorium searches for config files in this order:

  1. /usr/local/etc/scriptorium/config.yml
  2. /etc/scriptorium/config.yml

If neither file exists, Scriptorium continues with built-in defaults.

When --config <path> is provided, that file is required.

Minimal App Config

prompt_dir: ./examples/prompts

This is enough to use run and render when prompts select built-in profiles.

Production-Oriented App Config

prompt_dir: /opt/scriptorium/prompts
profile_dir: /opt/scriptorium/profiles
schema_dir: /opt/scriptorium/schemas

server:
  addr: 127.0.0.1:8080

defaults:
  render_format: text

App Config File (config.yml)

Top-level fields:

  • prompt_dir (optional): default prompt definition directory.
  • profile_dir (optional): default custom profile definition directory.
  • schema_dir (optional): base directory for schema files used by json_schema validation.
  • server.addr (optional): default listen address for serve.
  • defaults.render_format (optional): default render output format (text or json).

Built-in defaults:

  • schema_dir: .
  • server.addr: :8080
  • defaults.render_format: text

Validation behavior:

  • Config decoding is strict; unknown YAML fields are rejected.
  • Raw API key fields are not supported in config.yml.

Prompt Definition Files

Prompt definitions are YAML files anywhere under prompt_dir, including nested subdirectories.

Subdirectories are organizational only. Callers still select prompts by the YAML id, not by file path. For example, prompts/dnd/recap.yaml may still declare id: dnd.recap, and callers use --prompt dnd.recap.

Example:

id: generic.structured_events
version: "1.0.0"
default_profile: local-quality
description: Produce structured event JSON from a transcript.

inputs:
  - name: transcript
    required: true
    content_type: text/markdown
    description: Source transcript content
  - name: glossary
    required: false
    content_type: text/yaml
    description: Optional glossary context

messages:
  - role: system
    content_file: ./generic.structured_events.system.md
  - role: user
    content_file: ./generic.structured_events.user.md

output:
  format: json
  validation_mode: json_schema
  schema_path: structured_events.schema.json
  repair_attempts: 0

Field reference:

  • id (required): prompt identifier.
  • version (required): prompt version.
  • default_profile (optional): profile ID used when request does not provide profile_id.
  • description (optional): prompt description.
  • session_id (optional): Go-template string for OpenRouter sticky-routing session_id; rendered from request vars.
  • inputs (optional list): expected named inputs.
  • messages (required list): prompt message templates.
  • output (required object): output contract.

inputs[] fields:

  • name (required)
  • required (optional, boolean)
  • content_type (optional metadata)
  • description (optional)

messages[] fields:

  • role (required)
  • content or content_file (exactly one is required)
  • cache_control (optional object): provider prompt-cache metadata for this message

Message rules:

  • Repeated roles are allowed.
  • content_file is resolved relative to the prompt YAML file location.
  • Nested prompt files keep the same relative content_file behavior; ./recap.user.md next to dnd/recap.yaml resolves from dnd/.
  • Prompt decoding is strict; unknown YAML fields are rejected.
  • Duplicate prompt IDs are invalid. If multiple files declare the requested prompt ID, Scriptorium fails instead of choosing one.

messages[].cache_control fields:

  • type (required when cache_control is present): currently only ephemeral.
  • ttl (optional): currently only 1h; omitted from outbound requests when unset.

Example cache-controlled message:

messages:
  - role: system
    content_file: ./stable_context.md
    cache_control:
      type: ephemeral
      ttl: 1h
  - role: user
    content: |
      {{input "transcript"}}

Use cache control on stable reusable prompt content. Dynamic per-run inputs before the cache-controlled message change the provider cache key.

Example prompt-level session ID:

session_id: "{{ .session_id }}"

When configured, session_id is rendered with the same variable context as messages. The rendered value is trimmed, omitted when empty, and rejected if longer than 256 characters. CLI callers pass the value through --var session_id=<value>; HTTP callers pass it through "vars": {"session_id": "<value>"}.

output fields:

  • format (required): text, markdown, or json.
  • validation_mode (required): none, basic, json, or json_schema.
  • schema_path (required when validation_mode: json_schema).
  • repair_attempts (required): integer >= 0.

Repair behavior boundary:

  • repair_attempts is part of the prompt contract.
  • CLI and HTTP currently construct the runner without a repairer, so normal run/serve execution does not perform output repair attempts.

Profile Definition Files

Scriptorium includes built-in execution profiles. Custom execution profiles are YAML files anywhere under profile_dir, including nested subdirectories.

Subdirectories are organizational only. Callers still select profiles by the YAML id, not by file path. For example, profiles/local/local-quality.yaml may still declare id: local-quality, and callers use --profile local-quality.

Example:

id: local-fast
endpoint: http://localhost:8000/v1
model: gpt-4o-mini
temperature: 0.2
max_tokens: 500
top_p: 1.0
timeout_seconds: 90
api_key_env: SCRIPTORIUM_API_KEY
service_tier: priority
reasoning_effort: medium
extra_params:
  provider_route: primary
  provider_options:
    retry_budget: 2

Field reference:

  • id (required)
  • endpoint (required)
  • model (required)
  • temperature (optional): range 0..2
  • max_tokens (optional): >= 0
  • top_p (optional): range 0..1
  • timeout_seconds (optional): >= 0
  • service_tier (optional): provider-specific request tier such as OpenRouter flex or priority
  • reasoning_effort (optional): serialized as top-level reasoning_effort in outbound chat-completions requests
  • api_key_env (optional)
  • extra_params (optional map): JSON-compatible provider-specific parameters. Values may be strings, numbers, booleans, objects, or arrays.

Profile rules:

  • profile_dir is optional. If omitted, only built-in profiles are available.
  • If profile_dir is set, custom profiles from that directory override built-in profiles with the same id.
  • Duplicate IDs within the custom profile directory are invalid. Matching IDs across custom and built-in profiles are valid override behavior.
  • Profile decoding is strict; unknown YAML fields are rejected.
  • Raw api_key is rejected; use api_key_env.
  • If api_key_env is set, that environment variable must be set when preparing/running.
  • Duplicate profile IDs are invalid. If multiple files declare the requested profile ID, Scriptorium fails instead of choosing one.
  • extra_params keys must not be empty and must not collide with reserved outbound request fields: model, session_id, messages, temperature, max_tokens, top_p, service_tier, reasoning_effort, or response_format.

Current outbound request behavior:

  • The OpenAI-compatible client currently serializes: model, optional session_id, messages, temperature, max_tokens, top_p, service_tier, reasoning_effort, optional response_format for json_schema prompts, and extra_params.
  • extra_params are flattened into provider-specific top-level JSON request fields. They are not wrapped in an extra_params object on the outbound provider request.
  • Messages without cache_control serialize with string content.
  • Messages with cache_control serialize as a single text content-block array containing cache_control.

Schema Behavior

Schemas are JSON files, typically in schema_dir.

Rules:

  • output.validation_mode: json_schema requires output.schema_path.
  • Relative schema_path values resolve from schema_dir, including explicit nested paths such as dnd/structured_events.schema.json.
  • Absolute schema_path values are used directly.
  • Scriptorium does not recursively search schemas by basename; nested schemas must be referenced by their relative path.
  • Missing or invalid schema documents cause runtime validation errors.
  • Invalid generated JSON causes validation status failed (not a runtime error).

Supported artifact reference types for request inputs are file and inline.

Secrets Handling

  • Keep secret values in environment variables.
  • Store only environment-variable names in profile api_key_env.
  • Do not put raw API keys in config, prompts, profiles, CLI flags, or HTTP request bodies.

Maintained Examples

  • App config: examples/config.yml
  • Prompt examples: examples/prompts/
  • Custom profile examples: examples/profiles/
  • Schema examples: examples/schemas/
  • Input fixtures: examples/fixtures/
  • Render example script: examples/render-markdown-summary.sh
  • HTTP request example: examples/http-run.json

Example organizational layout:

examples/prompts/dnd/recap.yaml
examples/profiles/local/local-quality.yaml
examples/schemas/dnd/structured_events.schema.json

Integration References