Refresh primary documentation references

This commit is contained in:
2026-07-05 03:02:11 +00:00
parent d5d7a222a4
commit 574f88bd6a
4 changed files with 287 additions and 207 deletions

View File

@@ -1,8 +1,12 @@
# scriptorium
Scriptorium is a config-driven prompt execution engine.
Scriptorium is a narrow prompt-execution application for rendering prompt
requests, running them against OpenAI-compatible chat-completions endpoints, and
serving the same run workflow over HTTP.
It separates prompt definitions (what to generate) from execution profiles (how to call an OpenAI-compatible model endpoint), then runs or renders a prepared request from named input artifacts.
It keeps prompt definitions, execution profiles, schemas, and input artifacts as
separate files so prompts can be reviewed and reused without baking model
runtime settings into application code.
## Quickstart
@@ -23,16 +27,19 @@ This command renders the prepared prompt and effective runtime settings without
- [CLI reference](docs/cli.md)
- [Configuration reference](docs/config.md)
- [HTTP API reference](docs/api.md)
- [Operations guide](docs/operations.md)
- [Troubleshooting](docs/troubleshooting.md)
- [Consumer integration overview](docs/consumers/api.md)
- [Go library package](docs/consumers/pkg-scriptorium.md)
- [HTTP API reference](docs/api.md)
- [OpenAI-compatible chat integration](docs/integrations/openai-compatible-chat.md)
- [Subprocess integration](docs/integrations/subprocess.md)
- [OpenAI-compatible chat integration](docs/integrations/openai-compatible-chat.md)
- [Architecture policy](docs/policy/architecture.md)
## Examples
- `examples/config.yml`
- `examples/config.full.yml`
- `examples/render-markdown-summary.sh`
- `examples/http-run.json`
- `examples/go-library/prepare`

View File

@@ -10,127 +10,195 @@ go run ./cmd/scriptorium render \
--input glossary=./examples/fixtures/glossary.yml
```
`render` prepares and formats the prompt without calling an LLM.
`render` prepares the prompt, loads input artifacts, resolves the execution
profile, and prints the prepared request without calling an LLM.
## Command Overview
- `scriptorium run`: prepare prompt, call the configured LLM, write generated output, print a run summary.
- `scriptorium render`: prepare prompt only; write prepared-run output as `text` or `json`.
- `scriptorium serve`: start the HTTP server.
- `scriptorium run`: prepare a prompt, call the configured LLM, write generated output, and print a run summary.
- `scriptorium render`: prepare a prompt only; write prepared-run output as `text` or `json`.
- `scriptorium serve`: start the HTTP server for `POST /v1/runs`.
Integration references:
Canonical related references:
- [Configuration reference](config.md)
- [HTTP API reference](api.md)
- [Subprocess integration](integrations/subprocess.md)
## Common Argument Rules
## Common Rules
- `--config` is supported by `run`, `render`, and `serve`.
- `run` and `render` require:
- `--prompt`
- at least one `--input`
- an effective `prompt_dir` from flags or config
- `serve` requires an effective `prompt_dir` from flags or config.
- `profile_dir` is optional. If omitted, only built-in profiles are available; if provided, custom profiles override built-ins with the same ID.
- Built-in profile IDs are listed in the [configuration reference](config.md#profile-definition-files).
- Positional arguments are rejected.
- Prompt cache control is configured in prompt YAML (`messages[].cache_control`), not with CLI flags.
- Provider-specific `reasoning_effort` and `extra_params` are configured in profile YAML or HTTP model overrides, not with CLI flags.
- `run` and `render` require `--prompt`, at least one `--input`, and an effective `prompt_dir`.
- `serve` requires an effective `prompt_dir`.
- `profile_dir` is optional. Without it, only built-in profiles are available.
- If `profile_dir` is set, custom profiles override built-in profiles with the same ID.
- Prompt cache control, `session_id`, structured output, and provider-specific profile fields are configured in YAML, not with CLI flags.
Config precedence is:
1. built-in defaults
2. config file values
3. CLI flags
## Flag Reference
### `scriptorium run`
- `--config <path>`: app config file path.
```bash
scriptorium run [flags]
```
Required through flags or config:
- `--prompt-dir <dir>`: prompt definition directory.
Required as flags:
- `--prompt <id>`: prompt ID to execute.
- `--input name=path`: input file mapping. Repeat or use comma-separated mappings.
Optional flags:
- `--config <path>`: application config file.
- `--profile-dir <dir>`: custom profile definition directory.
- `--schema-dir <dir>`: schema base directory for `json_schema` validation.
- `--prompt <id>`: prompt ID to execute. Required.
- `--prompt-id <id>`: deprecated alias for `--prompt`.
- `--profile <id>`: explicit profile override.
- `--profile-id <id>`: deprecated alias for `--profile`.
- `--input name=path`: input mapping (repeatable, comma-separated accepted).
- `--var name=value`: template variable mapping (repeatable, comma-separated accepted).
- `--out <path>`: write artifact body to file instead of stdout.
- `--profile <id>`: execution profile override. If omitted, the prompt `default_profile` is used.
- `--var name=value`: template variable mapping. Repeat or use comma-separated mappings.
- `--out <path>`: write generated artifact body to a file instead of stdout.
- `--llm-base-url <url>`: runtime endpoint override.
- `--model <name>`: runtime model override.
- `--api-key-env <name>`: runtime API key environment-variable name override.
- `--api-key-env <name>`: runtime API-key environment variable name override.
- `--temperature <float>`: runtime temperature override.
- `--max-tokens <int>`: runtime max tokens override.
- `--top-p <float>`: runtime top-p override.
- `--timeout <duration>`: runtime timeout override (Go duration syntax, for example `30s`, `2m`).
- `--timeout <duration>`: runtime timeout override using Go duration syntax, such as `30s` or `2m`.
Numeric runtime override flags are presence-aware:
Deprecated aliases:
- omitted numeric flags preserve the selected profile/default value
- explicit zero values override the selected profile/default value (`--temperature 0`, `--max-tokens 0`, `--top-p 0`, `--timeout 0s`)
- `--prompt-id <id>`: alias for `--prompt`.
- `--profile-id <id>`: alias for `--profile`.
Runtime override notes:
- Omitted numeric override flags preserve the selected profile/default value.
- Explicit zero values override the selected profile/default value.
- `--timeout 0s` disables the outbound HTTP client timeout for that request.
- There is no raw API-key flag; use `--api-key-env`.
### `scriptorium render`
- Supports the same flags as `run`, except:
- no `--schema-dir` flag.
- Adds:
- `--format text|json`: prepared-run output format.
```bash
scriptorium render [flags]
```
Required through flags or config:
- `--prompt-dir <dir>`: prompt definition directory.
Required as flags:
- `--prompt <id>`: prompt ID to render.
- `--input name=path`: input file mapping. Repeat or use comma-separated mappings.
Optional flags:
- `--config <path>`: application config file.
- `--prompt-dir <dir>`: prompt definition directory.
- `--profile-dir <dir>`: custom profile definition directory.
- `--profile <id>`: execution profile override.
- `--var name=value`: template variable mapping. Repeat or use comma-separated mappings.
- `--out <path>`: write prepared-run output to a file instead of stdout.
- `--llm-base-url <url>`: runtime endpoint override for the prepared request.
- `--model <name>`: runtime model override for the prepared request.
- `--api-key-env <name>`: runtime API-key environment variable name override.
- `--temperature <float>`: runtime temperature override.
- `--max-tokens <int>`: runtime max tokens override.
- `--top-p <float>`: runtime top-p override.
- `--timeout <duration>`: runtime timeout override using Go duration syntax.
- `--format text|json`: prepared-run output format. Defaults to config `defaults.render_format`, then `text`.
Deprecated aliases:
- `--prompt-id <id>`: alias for `--prompt`.
- `--profile-id <id>`: alias for `--profile`.
Notes:
- `render` still resolves profile and runtime settings.
- `render` still validates that `api_key_env` exists if the selected profile or overrides require it.
- `render` resolves profiles, loads schemas for `json_schema` prompts, and validates `api_key_env`.
- `render` does not accept `--schema-dir`; use config `schema_dir` for render-time schema lookup.
- `render` does not call the LLM.
### `scriptorium serve`
- `--config <path>`: app config file path.
```bash
scriptorium serve [flags]
```
Required through flags or config:
- `--prompt-dir <dir>`: prompt definition directory.
Optional flags:
- `--config <path>`: application config file.
- `--addr <listen-address>`: HTTP listen address.
- `--prompt-dir <dir>`: prompt definition directory.
- `--profile-dir <dir>`: custom profile definition directory.
- `--schema-dir <dir>`: schema base directory for `json_schema` validation.
- `--artifact-root <dir>`: base directory for HTTP `file` input references.
- `--max-request-bytes <n>`: maximum HTTP request body bytes; `0` disables this limit.
- `--max-artifact-bytes <n>`: maximum HTTP file artifact bytes; `0` disables this limit.
- `--max-response-bytes <n>`: maximum encoded HTTP response body bytes; `0` disables this limit.
- `--max-request-bytes <n>`: maximum HTTP request body bytes; `0` disables the limit.
- `--max-artifact-bytes <n>`: maximum HTTP file artifact bytes; `0` disables the limit.
- `--max-response-bytes <n>`: maximum encoded HTTP response body bytes; `0` disables the limit.
Notes:
- `serve` does not accept runtime model override flags such as `--model` or `--llm-base-url`.
- HTTP `file` input references are rejected unless an artifact root is configured through `server.artifact_root` or `--artifact-root`.
- `--artifact-root` and the HTTP size-limit flags affect only `serve`; `run` and `render` file input paths are unchanged.
- HTTP request fields and error codes are documented in the [HTTP API reference](api.md).
- HTTP `file` input references are rejected unless an artifact root is configured.
- HTTP size-limit flags affect only `serve`.
## Input And Variable Syntax
- `--input name=path` maps prompt input names to local file paths.
- `--var name=value` maps template variable names to values.
- If a prompt defines `session_id: "{{ .session_id }}"`, pass the OpenRouter sticky-routing value with `--var session_id=<value>`.
- `--var name=value` maps prompt template variables to string values.
- Both flags can be repeated.
- Both flags also support comma-separated batches, for example:
- `--input transcript=./t.md,glossary=./g.yml`
- `--var session_id=42,session_date=2026-05-04`
- Both flags also accept comma-separated mappings, such as `--input transcript=./t.md,glossary=./g.yml`.
- Values may contain `=` after the first separator, such as `--var note=a=b=c`.
- Empty names and empty values are rejected.
CLI `run` and `render` convert every `--input` mapping to a `file` artifact
reference. HTTP also supports `inline` input references; see [HTTP API
reference](api.md).
## Output Behavior
`run`:
- Writes generated artifact content to stdout by default.
- Writes generated artifact content to `--out` when provided.
- Prints run summary metadata to stderr on success.
- Appends `cached_tokens=<n> cache_write_tokens=<n>` to the summary only when the provider reports non-zero cache usage.
- Prints a success summary to stderr.
- Prints errors to stderr on failure.
`render`:
- Writes prepared-run output to stdout by default.
- Writes prepared-run output to `--out` when provided.
- Does not print a success summary line.
- Does not print a success summary.
`serve`:
- Logs startup and server errors to stderr.
## Exit Codes
- `0`: success.
- `1`: runtime/parse/config/load/render/generation/output-write error.
- `2`: `run` completed, output was generated, but validation status is `failed`.
When `run` exits `2`, output may already be written to stdout or `--out`.
- `1`: parse, config, load, render, generation, output-write, or runtime error.
- `2`: `run` completed and wrote output, but validation status is `failed`.
## Common Workflows
Render prompt inputs and template variables as JSON:
Render prompt inputs and variables as JSON:
```bash
go run ./cmd/scriptorium render \
@@ -142,7 +210,7 @@ go run ./cmd/scriptorium render \
--format json
```
Run a prompt with profile override and file output:
Run a prompt with an explicit profile and file output:
```bash
go run ./cmd/scriptorium run \
@@ -154,12 +222,12 @@ go run ./cmd/scriptorium run \
--out ./summary.md
```
Start the HTTP server with explicit config:
Start the HTTP server with example config:
```bash
go run ./cmd/scriptorium serve --config ./examples/config.yml
```
Copyable example script:
Copyable maintained script:
- `examples/render-markdown-summary.sh`

View File

@@ -2,30 +2,32 @@
## Config Discovery And Precedence
Application settings are loaded in this order:
Application settings are resolved in this order:
1. Built-in defaults
1. built-in defaults
2. `config.yml` values
3. CLI overrides
When `--config` is not provided, Scriptorium searches for config files in this order:
When `--config` is omitted, Scriptorium searches:
1. `/usr/local/etc/scriptorium/config.yml`
2. `/etc/scriptorium/config.yml`
If neither file exists, Scriptorium continues with built-in defaults.
If neither file exists, Scriptorium uses built-in defaults. When
`--config <path>` is provided, that file must exist and decode successfully.
When `--config <path>` is provided, that file is required.
## Minimal App Config
## Minimal Working Config
```yaml
prompt_dir: ./examples/prompts
```
This is enough to use `run` and `render` when prompts select built-in profiles.
This is enough for `run` and `render` when selected prompts use built-in
profiles. Set `profile_dir` when prompts or requests use custom profiles.
## Production-Oriented App Config
The maintained repository example is `examples/config.yml`.
## Production-Oriented Config
```yaml
prompt_dir: /opt/scriptorium/prompts
@@ -43,57 +45,48 @@ defaults:
render_format: text
```
## App Config File (`config.yml`)
The maintained full example is `examples/config.full.yml`.
## App Config Reference
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`).
| 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. |
Built-in defaults:
`server` fields:
- `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`
| 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. |
Validation behavior:
`defaults` fields:
- 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`.
| Field | Default | Description |
| --- | --- | --- |
| `defaults.render_format` | `text` | Default `render` output format: `text` or `json`. |
HTTP artifact root behavior:
Config rules:
- `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.
- 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`, 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`.
Prompt definitions are YAML files anywhere under `prompt_dir`. Nested
directories are organizational; callers select prompts by YAML `id`, not file
path.
Example:
@@ -126,84 +119,76 @@ output:
repair_attempts: 0
```
Field reference:
Prompt fields:
- `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.
| 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)
- `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
- 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.
- `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.
- Prompt YAML decoding is strict.
- Duplicate input names are invalid.
- Duplicate prompt IDs are invalid for a requested ID/version.
`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.
| Field | Required | Supported values |
| --- | --- | --- |
| `type` | yes | `ephemeral` |
| `ttl` | no | `1h` |
Example cache-controlled message:
`session_id` behavior:
```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>"}`.
- 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:
- `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`.
| 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 behavior boundary:
Repair 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.
- 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
Scriptorium includes built-in execution profiles. Custom execution profiles are YAML files anywhere under `profile_dir`, including nested subdirectories.
Execution profiles are YAML files anywhere under `profile_dir`. Nested
directories are organizational; callers select profiles by YAML `id`, not file
path.
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`.
Scriptorium also ships built-in profiles. Custom profiles override built-ins
with the same ID.
Example:
@@ -220,36 +205,44 @@ service_tier: priority
reasoning_effort: medium
extra_params:
provider_route: primary
provider_options:
retry_budget: 2
```
Field reference:
Profile fields:
- `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.
| 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_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.
- 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, 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`.
- 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 IDs:
Built-in profile catalog:
| Provider | ID | Model | API key env |
| --- | --- | --- | --- |
@@ -277,56 +270,55 @@ Built-in profile IDs:
| 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`.
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`, including explicit nested paths such as `dnd/structured_events.schema.json`.
- Relative `schema_path` values resolve from `schema_dir`.
- 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).
- 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.
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`.
## 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 profile `api_key_env`.
- Do not put raw API keys in config, prompts, profiles, CLI flags, or HTTP request bodies.
- 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
- App config: `examples/config.yml`
- 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 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
```
- 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)

13
examples/config.full.yml Normal file
View File

@@ -0,0 +1,13 @@
prompt_dir: ./examples/prompts
profile_dir: ./examples/profiles
schema_dir: ./examples/schemas
server:
addr: 127.0.0.1:8080
artifact_root: .
max_request_bytes: 16777216
max_artifact_bytes: 16777216
max_response_bytes: 16777216
defaults:
render_format: text