Files
scriptorium/docs/config.md

14 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
  artifact_root: /var/lib/scriptorium/artifacts
  max_request_bytes: 16777216
  max_artifact_bytes: 16777216
  max_response_bytes: 16777216

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.
  • server.artifact_root (optional): base directory for HTTP file input references.
  • server.max_request_bytes (optional): maximum HTTP request body size. 0 disables this limit.
  • server.max_artifact_bytes (optional): maximum HTTP file input artifact size. 0 disables this limit.
  • server.max_response_bytes (optional): maximum encoded HTTP response body size. 0 disables this limit.
  • defaults.render_format (optional): default render output format (text or json).

Built-in defaults:

  • schema_dir: .
  • server.addr: :8080
  • server.artifact_root: unset; HTTP file input references are rejected until configured.
  • server.max_request_bytes: 16777216 (16 MiB)
  • server.max_artifact_bytes: 16777216 (16 MiB)
  • server.max_response_bytes: 16777216 (16 MiB)
  • defaults.render_format: text

Validation behavior:

  • Config decoding is strict; unknown YAML fields are rejected.
  • HTTP size limit values must be greater than or equal to 0.
  • Raw API key fields are not supported in config.yml.

HTTP artifact root behavior:

  • server.artifact_root applies only to serve.
  • HTTP inline input references work without an artifact root.
  • HTTP file input references are resolved against server.artifact_root with lexical path checks.
  • Relative traversal and absolute paths that are lexically outside the root are rejected.
  • Symlinks inside the root are followed by the operating system, including symlinks that point outside the root. Do not make the artifact root writable by untrusted users.
  • CLI run and render file inputs keep their normal direct filesystem path behavior.

HTTP size-limit behavior:

  • The request limit covers the encoded JSON request body, including inline input bodies.
  • The artifact limit covers HTTP file input artifacts read through serve.
  • The response limit covers the final encoded JSON response, including generated artifact bodies and raw_model_output when requested.
  • Limits apply only to HTTP serve; CLI run and render keep direct filesystem behavior.

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.

Built-in profile IDs:

Provider ID Model API key env
aion-labs aion-2 aion-labs/aion-2.0 OPENROUTER_API_KEY
anthropic claude-fable-latest ~anthropic/claude-fable-latest OPENROUTER_API_KEY
anthropic claude-haiku-latest ~anthropic/claude-haiku-latest OPENROUTER_API_KEY
anthropic claude-opus-latest ~anthropic/claude-opus-latest OPENROUTER_API_KEY
anthropic claude-sonnet-latest ~anthropic/claude-sonnet-latest OPENROUTER_API_KEY
deepseek deepseek-3-2 deepseek/deepseek-v3.2 OPENROUTER_API_KEY
deepseek deepseek-4-pro deepseek/deepseek-v4-pro OPENROUTER_API_KEY
google gemini-2-flash google/gemini-2.5-flash OPENROUTER_API_KEY
google gemini-2-flash-lite google/gemini-2.5-flash-lite OPENROUTER_API_KEY
google gemini-2-pro google/gemini-2.5-pro OPENROUTER_API_KEY
google gemini-3-flash-lite google/gemini-3.1-flash-lite OPENROUTER_API_KEY
google gemini-flash-latest ~google/gemini-flash-latest OPENROUTER_API_KEY
google gemini-pro-latest ~google/gemini-pro-latest OPENROUTER_API_KEY
google gemma-4-31b google/gemma-4-31b-it:exacto OPENROUTER_API_KEY
minimax minimax-m2 minimax/minimax-m2.5 OPENROUTER_API_KEY
minimax minimax-m3 minimax/minimax-m3 OPENROUTER_API_KEY
mistral mistral-large-2512 mistralai/mistral-large-2512 OPENROUTER_API_KEY
mistral mistral-medium-3-5 mistralai/mistral-medium-3-5 OPENROUTER_API_KEY
mistral mistral-small-3 mistralai/mistral-small-3.2-24b-instruct OPENROUTER_API_KEY
mistral mistral-small-4 mistralai/mistral-small-2603 OPENROUTER_API_KEY
nvidia nemotron-3-ultra nvidia/nemotron-3-ultra-550b-a55b OPENROUTER_API_KEY
openai gpt-5-mini openai/gpt-5.4-mini OPENROUTER_API_KEY
openai gpt-5-nano openai/gpt-5.4-nano OPENROUTER_API_KEY

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. For HTTP serve, file references require server.artifact_root and must pass lexical containment checks against that root. CLI run and render file inputs are not restricted by server.artifact_root.

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