scriptorium

Scriptorium is a generic prompt-profile execution engine written in Go.

Given named input artifacts and a prompt profile, Scriptorium:

  1. Loads the profile.
  2. Resolves input artifact references.
  3. Renders prompt messages from templates.
  4. Calls an OpenAI-compatible LLM endpoint.
  5. Validates output if configured.
  6. Optionally performs bounded structured-output repair.
  7. Returns a generated artifact plus run metadata.

Where Scriptorium Fits

Scriptorium is not an orchestrator.

In the D&D workflow:

  • Narratio orchestrates the full pipeline.
  • WhisperX transcribes audio.
  • Seriatim merges transcripts.
  • Audita polishes transcripts.
  • Scriptorium generates final artifacts from prepared inputs.

D&D-specific behavior belongs in profiles, schemas, fixtures, and caller inputs, not in core Go logic.

Core Concepts

  • Prompt profile: YAML config that defines templates, model defaults, output format, and validation behavior.
  • Named inputs: logical input names (for example transcript, glossary) mapped to artifact references.
  • Artifact refs: currently file and inline are supported by readers used in v1 flows.
  • Template variables: key/value vars provided at run time and accessed in templates as {{.var_name}}.
  • Model target: endpoint/model and generation parameters (temperature, max_tokens, top_p, timeout_seconds).
  • Output format: text, markdown, or json.
  • Validation mode: none, basic, json, json_schema.
  • Repair attempts: bounded retries for structured modes (json, json_schema) when output validation fails.
  • Run metadata: IDs/hashes/model/timing/usage/validation details for auditability.

Build and Test

Build:

go build -o scriptorium ./cmd/scriptorium

Run tests:

go test ./...

Run CLI locally:

go run ./cmd/scriptorium run --help

CLI Usage

scriptorium run

Required flags:

  • --profile-dir
  • --profile-id
  • --input (repeatable name=path)

Optional flags:

  • --var (repeatable name=value)
  • --out
  • --llm-base-url
  • --llm-api-key
  • --model
  • --temperature
  • --max-tokens
  • --schema-dir
  • --timeout

If --llm-base-url and/or --model are omitted, profile model_defaults must provide them.

Markdown summary example:

go run ./cmd/scriptorium run \
  --profile-dir ./profiles \
  --profile-id generic.markdown_summary \
  --input transcript=./examples/fixtures/transcript.md \
  --input glossary=./examples/fixtures/glossary.yml \
  --out ./out.md

Same run with explicit local OpenAI-compatible endpoint (for example vLLM):

go run ./cmd/scriptorium run \
  --profile-dir ./profiles \
  --profile-id generic.markdown_summary \
  --input transcript=./examples/fixtures/transcript.md \
  --input glossary=./examples/fixtures/glossary.yml \
  --llm-base-url http://localhost:8000/v1 \
  --model gpt-4o-mini \
  --out ./out.md

Passing template variables:

go run ./cmd/scriptorium run \
  --profile-dir ./profiles \
  --profile-id generic.markdown_summary \
  --input transcript=./examples/fixtures/transcript.md \
  --input glossary=./examples/fixtures/glossary.yml \
  --var session_date=2026-05-04 \
  --var facilitator="Eris" \
  --out ./out.md

Output behavior:

  • Artifact content goes to stdout unless --out is set.
  • Summaries and errors are written to stderr.
  • Exit code 2 indicates run succeeded but validation status is failed.

scriptorium serve

Starts HTTP API.

Required flags:

  • --profile-dir
  • --llm-base-url

Common optional flags:

  • --addr (default :8080)
  • --schema-dir (default .)
  • --llm-api-key
  • --model
  • --timeout (default 10m)

HTTP API

Run endpoint:

  • POST /v1/runs

Request example:

{
  "profile_id": "generic.structured_events",
  "profile_version": "1.0.0",
  "inputs": {
    "transcript": {"type": "file", "uri": "./examples/fixtures/transcript.md"},
    "glossary": {"type": "file", "uri": "./examples/fixtures/glossary.yml"}
  },
  "vars": {
    "session_date": "2026-05-04"
  },
  "model": {
    "endpoint": "http://localhost:8000/v1",
    "model": "gpt-4o-mini",
    "temperature": 0.0,
    "max_tokens": 600,
    "top_p": 1.0,
    "timeout_seconds": 120
  }
}

Response shape:

{
  "artifact": {
    "name": "output",
    "content_type": "application/json",
    "body": "{...}",
    "uri": "",
    "size": 123,
    "hash": "..."
  },
  "validation": {
    "status": "passed",
    "mode": "json_schema",
    "errors": [],
    "schema_path": "structured_events.schema.json",
    "repair_attempts": 0,
    "is_valid": true
  },
  "metadata": {
    "run_id": "xxxxxxxx-xxxx-4xxx-8xxx-xxxxxxxxxxxx",
    "profile_id": "generic.structured_events",
    "profile_version": "1.0.0",
    "profile_hash": "...",
    "model_name": "gpt-4o-mini",
    "endpoint": "http://localhost:8000/v1",
    "model_params": {
      "endpoint": "http://localhost:8000/v1",
      "model": "gpt-4o-mini",
      "temperature": 0,
      "max_tokens": 600,
      "top_p": 1,
      "timeout_seconds": 120
    },
    "input_hashes": {"transcript": "...", "glossary": "..."},
    "prompt_hash": "...",
    "usage": {"prompt_tokens": 10, "completion_tokens": 20, "total_tokens": 30},
    "start_time": "...",
    "end_time": "...",
    "duration_ms": 1523,
    "validation_mode": "json_schema",
    "validation_status": "passed",
    "repair_attempts_used": 0
  },
  "raw_model_output": "{...}"
}

Validation content failures are returned as successful run responses (200) with validation.status = "failed"; raw model output is preserved in raw_model_output.

Error response shape:

{
  "error": {
    "code": "artifact_read_failed",
    "message": "failed to read input artifact"
  }
}

Prompt Profile Authoring

Minimal Markdown profile

id: generic.markdown_summary
version: "1.0.0"
expected_inputs:
  - transcript
templates:
  - role: system
    content: "You are a concise assistant."
  - role: user
    content: |
      Summarize:
      {{input "transcript"}}
model_defaults:
  endpoint: http://localhost:8000/v1
  model: gpt-4o-mini
  temperature: 0.2
  max_tokens: 700
output_format: markdown
validation:
  validation_mode: basic

Structured JSON profile with schema validation

id: generic.structured_events
version: "1.0.0"
expected_inputs:
  - transcript
templates:
  - role: system
    content: "Return only JSON."
  - role: user
    content: |
      Extract events from:
      {{input "transcript"}}
model_defaults:
  endpoint: http://localhost:8000/v1
  model: gpt-4o-mini
output_format: json
validation:
  format: json
  validation_mode: json_schema
  schema_path: structured_events.schema.json
  repair_attempts: 1

repair_attempts is bounded. Repair is attempted only for structured validation modes.

Validation Modes

Supported modes:

  • none: skipped validation result.
  • basic: fails if output is empty/whitespace.
  • json: output must parse as JSON.
  • json_schema: output must parse as JSON and satisfy the configured schema.

Validation failures caused by output content are represented in validation and do not discard raw model output.

Repository Examples

  • Profiles: profiles/
  • Schemas: schemas/
  • Fixtures: examples/fixtures/
  • Local experimentation: local-test/

Development Notes

  • Core is generic and follows a ports-and-adapters style.
  • Domain/usecase packages do not depend on HTTP/CLI/wire types.
  • To add a new LLM adapter: implement internal/llm.Client.
  • To add a new artifact reader: implement/extend internal/artifact.Reader routing.
  • To add a new validation mode: extend internal/validate and keep run semantics stable.
Description
Scriptorium is a a prompt-profile execution engine written in Go.
Readme BSD-3-Clause 2.4 MiB
v0.12.0 Latest
2026-07-28 19:55:31 +00:00
Languages
Go 100%