Files
scriptorium/docs/config.md

325 lines
11 KiB
Markdown

# Configuration Reference
## Config Discovery And Precedence
Application settings are resolved in this order:
1. built-in defaults
2. `config.yml` values
3. CLI overrides
When `--config` is omitted, Scriptorium searches:
1. `/usr/local/etc/scriptorium/config.yml`
2. `/etc/scriptorium/config.yml`
If neither file exists, Scriptorium uses built-in defaults. When
`--config <path>` is provided, that file must exist and decode successfully.
## Minimal Working Config
```yaml
prompt_dir: ./examples/prompts
```
This is enough for `run` and `render` when selected prompts use built-in
profiles. Set `profile_dir` when prompts or requests use custom profiles.
The maintained repository example is `examples/config.yml`.
## Production-Oriented Config
```yaml
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
```
The maintained full example is `examples/config.full.yml`.
## App Config Reference
Top-level fields:
| Field | Default | Description |
| --- | --- | --- |
| `prompt_dir` | unset | Directory containing prompt definition YAML files. Required effectively by `run`, `render`, and `serve`. |
| `profile_dir` | unset | Directory containing custom profile YAML files. Built-in profiles remain available when unset. |
| `schema_dir` | `.` | Base directory for relative JSON Schema paths. |
| `server` | `{}` | HTTP service settings used by `serve`. |
| `defaults` | `{}` | Adapter defaults. |
`server` fields:
| Field | Default | Description |
| --- | --- | --- |
| `server.addr` | `:8080` | Listen address for `serve`. |
| `server.artifact_root` | unset | Base directory for HTTP `file` input references. Without it, HTTP file refs are rejected. |
| `server.max_request_bytes` | `16777216` | Maximum encoded HTTP request body bytes. `0` disables the limit. |
| `server.max_artifact_bytes` | `16777216` | Maximum HTTP file artifact bytes. `0` disables the limit. |
| `server.max_response_bytes` | `16777216` | Maximum encoded HTTP response bytes. `0` disables the limit. |
`defaults` fields:
| Field | Default | Description |
| --- | --- | --- |
| `defaults.render_format` | `text` | Default `render` output format: `text` or `json`. |
Config rules:
- YAML decoding is strict; unknown fields are rejected.
- HTTP size limits must be greater than or equal to `0`.
- Empty string config values are ignored.
- Raw API key fields are not supported in app config.
## Prompt Definition Files
Prompt definitions are YAML files anywhere under `prompt_dir`. Nested
directories are organizational; callers select prompts by YAML `id`, not file
path.
Example:
```yaml
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
```
Prompt fields:
| Field | Required | Description |
| --- | --- | --- |
| `id` | yes | Prompt identifier used by `--prompt` and HTTP `prompt_id`. |
| `version` | yes | Prompt version. |
| `default_profile` | no | Profile ID used when a request does not provide a profile. |
| `description` | no | Human-readable description. |
| `session_id` | no | Go-template string rendered from request vars and forwarded as provider `session_id` when non-empty. |
| `inputs` | no | Named input declarations. |
| `messages` | yes | Chat message templates. |
| `output` | yes | Output format and validation contract. |
`inputs[]` fields:
- `name` (required)
- `required` (optional boolean)
- `content_type` (optional metadata)
- `description` (optional)
`messages[]` fields:
- `role` (required)
- exactly one of `content` or `content_file`
- `cache_control` (optional)
Message rules:
- `content_file` resolves relative to the prompt YAML file location.
- Repeated roles are allowed.
- Prompt YAML decoding is strict.
- Duplicate input names are invalid.
- Duplicate prompt IDs are invalid for a requested ID/version.
`messages[].cache_control` fields:
| Field | Required | Supported values |
| --- | --- | --- |
| `type` | yes | `ephemeral` |
| `ttl` | no | `1h` |
`session_id` behavior:
- Rendered with the same variable context as message templates.
- Trimmed and omitted when empty.
- Rejected when longer than 256 Unicode code points.
- CLI callers pass variables with `--var`; HTTP callers use `vars`.
`output` fields:
| Field | Required | Supported values |
| --- | --- | --- |
| `format` | yes | `text`, `markdown`, `json` |
| `validation_mode` | yes | `none`, `basic`, `json`, `json_schema` |
| `schema_path` | only for `json_schema` | Relative to `schema_dir` unless absolute. |
| `repair_attempts` | yes | Integer greater than or equal to `0`. |
Repair boundary:
- `repair_attempts` is part of the prompt contract.
- The current CLI and HTTP wiring constructs the runner without a repairer, so normal `run` and `serve` execution does not perform repair attempts.
## Profile Definition Files
Execution profiles are YAML files anywhere under `profile_dir`. Nested
directories are organizational; callers select profiles by YAML `id`, not file
path.
Scriptorium also ships built-in profiles. Custom profiles override built-ins
with the same ID.
Example:
```yaml
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
```
Profile fields:
| Field | Required | Description |
| --- | --- | --- |
| `id` | yes | Profile identifier. |
| `endpoint` | yes | OpenAI-compatible base URL including `/v1`. |
| `model` | yes | Provider model name. |
| `temperature` | no | Range `0..2`. |
| `max_tokens` | no | Integer greater than or equal to `0`. |
| `top_p` | no | Range `0..1`. |
| `timeout_seconds` | no | Integer greater than or equal to `0`. |
| `service_tier` | no | Provider-specific request tier. |
| `reasoning_effort` | no | Provider-specific reasoning setting. |
| `api_key_env` | no | Environment variable name containing the API key. |
| `extra_params` | no | JSON-compatible provider-specific top-level request fields. |
Execution defaults before profile/request overrides:
| Field | Default |
| --- | --- |
| `temperature` | `0.0` |
| `max_tokens` | `0` |
| `top_p` | `1.0` |
| `timeout_seconds` | `600` |
Profile rules:
- Profile YAML decoding is strict.
- Duplicate custom profile IDs are invalid.
- Matching custom and built-in IDs are valid override behavior.
- Raw `api_key` is rejected; use `api_key_env`.
- If `api_key_env` is set, the named environment variable must be set before `run`, `render`, or HTTP execution can prepare the request.
- Profile numeric fields merge by non-zero value. Request overrides are presence-aware, so explicit zero values are supported through CLI flags or HTTP model overrides.
- `extra_params` keys must not be empty and must not collide with reserved outbound fields: `model`, `session_id`, `messages`, `temperature`, `max_tokens`, `top_p`, `service_tier`, `reasoning_effort`, or `response_format`.
Built-in profile catalog:
| 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` |
## Schema Behavior
Schemas are JSON files, typically under `schema_dir`.
Rules:
- `output.validation_mode: json_schema` requires `output.schema_path`.
- Relative `schema_path` values resolve from `schema_dir`.
- Absolute `schema_path` values are used directly.
- Nested schemas must be referenced by relative path; schemas are not searched recursively by basename.
- Missing or invalid schema documents are runtime validation errors.
- Invalid generated JSON produces validation status `failed`, not a runtime error.
## Artifact References
Supported request input artifact reference types are:
- `file`
- `inline`
CLI `run` and `render` create `file` references from `--input name=path`.
HTTP `file` references require `server.artifact_root` or `serve
--artifact-root`. Relative file URIs resolve under that root. Absolute paths
and relative traversal outside the root are rejected by lexical checks. Symlinks
inside the root are followed by the operating system, including symlinks that
point outside the root.
HTTP `inline` references do not require an artifact root.
## Secrets Handling
- Keep secret values in environment variables.
- Store only environment-variable names in `api_key_env`.
- Do not put raw API keys in config, prompts, profiles, CLI arguments, examples, or HTTP request bodies.
## Maintained Examples
- Minimal app config: `examples/config.yml`
- Full app config: `examples/config.full.yml`
- Prompt examples: `examples/prompts/`
- Custom profile examples: `examples/profiles/`
- Schema examples: `examples/schemas/`
- Input fixtures: `examples/fixtures/`
- Render script: `examples/render-markdown-summary.sh`
- HTTP request-shape example: `examples/http-run.json`
## Integration References
- [CLI reference](cli.md)
- [HTTP API reference](api.md)
- [Outbound OpenAI-compatible contract](integrations/openai-compatible-chat.md)