301 lines
12 KiB
Markdown
301 lines
12 KiB
Markdown
# 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
|
|
|
|
```yaml
|
|
prompt_dir: ./examples/prompts
|
|
```
|
|
|
|
This is enough to use `run` and `render` when prompts select built-in profiles.
|
|
|
|
## Production-Oriented App Config
|
|
|
|
```yaml
|
|
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:
|
|
|
|
```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
|
|
```
|
|
|
|
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:
|
|
|
|
```yaml
|
|
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:
|
|
|
|
```yaml
|
|
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:
|
|
|
|
```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
|
|
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`.
|
|
|
|
## 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:
|
|
|
|
```text
|
|
examples/prompts/dnd/recap.yaml
|
|
examples/profiles/local/local-quality.yaml
|
|
examples/schemas/dnd/structured_events.schema.json
|
|
```
|
|
|
|
## Integration References
|
|
|
|
- [Inbound HTTP contract](integrations/http-api.md)
|
|
- [Outbound OpenAI-compatible contract](integrations/openai-compatible-chat.md)
|