2026-07-26 14:16:09 +00:00
# Package `scriptorium`
2026-07-04 14:24:06 +00:00
Import path:
```go
import "gitea.maximumdirect.net/eric/scriptorium"
```
2026-07-26 14:16:09 +00:00
This is the canonical public Go contract for in-process prompt preparation and
execution. Prompt, profile, and schema file formats are defined in the
[configuration reference ](../config.md ).
2026-07-05 03:09:32 +00:00
2026-07-26 14:16:09 +00:00
## Engine Construction
2026-07-05 03:09:32 +00:00
2026-07-26 14:16:09 +00:00
`NewEngine(Config, ...Option)` constructs an engine. `Config` has these
fields:
2026-07-05 03:09:32 +00:00
2026-07-26 14:16:09 +00:00
| Field | Meaning |
2026-07-05 03:09:32 +00:00
| --- | --- |
2026-07-26 14:16:09 +00:00
| `PromptDir` | Prompt-definition directory, required unless a prompt source option is supplied. |
| `ProfileDir` | Optional custom profile directory over built-ins. |
| `SchemaDir` | Schema directory; empty uses `.` . |
2026-07-26 18:31:06 -05:00
| `Timeout` | Transport-wide safety cap for the built-in OpenAI-compatible client when `HTTPClient` is absent or has a non-positive timeout. A non-positive value uses the internal ten-minute default. |
| `HTTPClient` | Optional HTTP client for that built-in client. It is cloned; a positive `Timeout` on it is the transport cap and takes precedence over `Config.Timeout` . A non-positive client timeout is treated as unset. |
2026-07-04 17:02:09 +00:00
2026-07-26 14:16:09 +00:00
Nil options are ignored. Invalid construction, including
2026-07-28 00:35:54 +00:00
`WithLLMClient(nil)` and `WithArtifactReader(nil)` , returns an error matching
`ErrInvalidConfig` .
2026-07-04 17:02:09 +00:00
2026-07-26 18:31:06 -05:00
Profile and request `timeout_seconds` values select a per-generation-call
deadline independently of the transport cap. An explicit request override of
zero disables that generation deadline only. The complete interaction with the
caller context is defined in the
[OpenAI-compatible integration contract ](../integrations/openai-compatible-chat.md#authentication-and-timeout ).
2026-07-26 17:42:44 +00:00
2026-07-26 14:16:09 +00:00
Source options replace their matching directory source:
2026-07-04 17:02:09 +00:00
2026-07-26 14:16:09 +00:00
- prompts: `WithPromptFS(fsys, root)` , `WithPromptFile(path)` ;
- profiles: `WithProfileFS(fsys, root)` , `WithProfileFile(path)` , and
`WithProfiles(profiles...)` ;
- schemas: `WithSchemaFS(fsys, root)` , `WithSchemaFile(path)` ; and
2026-07-28 00:35:54 +00:00
- LLM client: `WithLLMClient(client)` ; and
- artifact reader: `WithArtifactReader(reader)` .
2026-07-04 17:02:09 +00:00
2026-07-26 14:16:09 +00:00
`fs.FS` prompt-content and schema paths stay inside their configured roots.
2026-07-26 17:43:42 +00:00
Single-file prompt and profile sources are selected by their YAML `id` , not
their file names. `WithPromptFile` resolves relative `content_file` paths from
the prompt file's directory. `WithSchemaFile` exposes its schema by the schema
file's base name. In-memory profiles take precedence over an explicit or
directory-backed profile source, which in turn takes precedence over built-ins.
File and filesystem sources use the format and credential rules in the
[configuration reference ](../config.md ).
2026-07-05 03:09:32 +00:00
2026-07-26 14:16:09 +00:00
## Prepare And Run
2026-07-05 03:09:32 +00:00
2026-07-26 14:16:09 +00:00
`Prepare(ctx, request)` resolves the prompt, profile, input artifacts,
validation contract, and rendered messages without calling an LLM.
`Run(ctx, request)` performs that preparation, calls the configured client,
and validates generated content.
2026-07-04 17:23:34 -05:00
```go
2026-07-26 14:16:09 +00:00
engine, err := scriptorium.NewEngine(scriptorium.Config{
PromptDir: "./examples/prompts",
ProfileDir: "./examples/profiles",
2026-07-04 17:23:34 -05:00
})
2026-07-26 14:16:09 +00:00
if err != nil {
return err
}
2026-07-04 17:23:34 -05:00
2026-07-04 14:24:06 +00:00
prepared, err := engine.Prepare(ctx, scriptorium.RunRequest{
PromptID: "generic.markdown_summary",
Inputs: map[string]scriptorium.ArtifactRef{
"transcript": scriptorium.File("./examples/fixtures/transcript.md"),
},
})
if err != nil {
return err
}
2026-07-26 14:16:09 +00:00
_ = prepared.Messages
2026-07-04 14:24:06 +00:00
```
2026-07-26 14:16:09 +00:00
The maintained package example is
[`examples/go-library/prepare` ](../../examples/go-library/prepare ).
2026-07-04 14:24:06 +00:00
2026-07-26 14:16:09 +00:00
`PreparedRun` exposes prompt, selected-profile, effective-model, output
contract, structured-output, input-hash, rendered-message, and timing
information. It does not include a resolved API key, model output, validation
result, or target-presence metadata.
2026-07-04 14:24:06 +00:00
2026-07-26 14:16:09 +00:00
`RunResult` adds run ID, artifact, raw output, validation, model metadata,
usage, and duration. Generated-content validation failures return a result with
`Validation.Status == ValidationFailed` ; schema or validator runtime failures
return an error matching `ErrValidation` .
2026-07-04 14:24:06 +00:00
2026-07-26 14:16:09 +00:00
## Public Values
2026-07-05 03:09:32 +00:00
2026-07-26 14:16:09 +00:00
`ArtifactRef` has `Type` , `URI` , and `Body` ; `Artifact` has `Name` ,
`ContentType` , `Body` , `URI` , `Size` , and `Hash` . `ExecutionTarget` exposes the
effective endpoint, model, numeric settings, credential-environment name,
service tier, reasoning effort, and extra parameters. `ValidationResult`
contains status, mode, errors, schema path, repair attempts, and validity.
2026-07-05 03:09:32 +00:00
2026-07-26 14:16:09 +00:00
The exported constants define these serialized values:
2026-07-05 03:09:32 +00:00
2026-07-26 14:16:09 +00:00
- artifact types: `inline` and `file` ;
- output formats: `text` , `markdown` , and `json` ;
- validation modes: `none` , `basic` , `json` , and `json_schema` ; and
- validation statuses: `passed` , `failed` , and `skipped` .
2026-07-04 14:24:06 +00:00
2026-07-26 14:16:09 +00:00
`TokenUsage` reports prompt, completion, total, cached, and cache-write token
counts. `RenderedPrompt` , `RenderedMessage` , `CacheControl` , and
`StructuredOutputSpec` are the public shapes used by injected LLM clients.
2026-07-04 23:17:44 +00:00
2026-07-28 00:35:54 +00:00
`ArtifactReader` implements
`Read(context.Context, ArtifactRef) (*Artifact, error)` . Supplying it through
`WithArtifactReader` replaces the engine's default inline and file reader for
all inputs. Reader errors remain available through `errors.Is` alongside
`ErrArtifactLoad` ; a nil artifact with no error is treated as an artifact-load
failure. Readers must supply artifact metadata and should not retain or mutate
the caller's values.
2026-07-26 14:16:09 +00:00
## Requests, Inputs, And Overrides
2026-07-04 16:55:01 +00:00
2026-07-26 14:16:09 +00:00
`RunRequest` fields are `PromptID` , `PromptVersion` , `ProfileID` ,
`APIKey` , `Inputs` , `Vars` , `Execution` , `Validation` , and
`Metadata` .
2026-07-04 14:24:06 +00:00
2026-07-26 14:16:09 +00:00
Input helpers are:
2026-07-04 14:24:06 +00:00
2026-07-26 14:16:09 +00:00
- `File(path)` for a file-backed artifact;
- `Inline(body)` for inline content; and
- `InlineWithURI(uri, body)` for inline content with URI metadata.
2026-07-04 14:24:06 +00:00
2026-07-26 14:16:09 +00:00
Required declared inputs must be supplied. Template rendering must also resolve
every input name the prompt actually references. Extra entries in `Inputs`
are not rejected solely because they are undeclared.
2026-07-04 14:24:06 +00:00
2026-07-26 14:16:09 +00:00
`ExecutionTargetOverride` supplies endpoint, model, credential-environment,
service-tier, reasoning-effort, and extra-parameter overrides. Its numeric
fields (`Temperature` , `MaxTokens` , `TopP` , and `TimeoutSeconds` ) are
pointers so explicit zero values are preserved. `OutputContract` supplies
`Format` , `ValidationMode` , `SchemaPath` , and `RepairAttempts` .
2026-07-04 14:24:06 +00:00
2026-07-26 14:16:09 +00:00
`ExtraParams` accepts JSON-compatible values: strings, booleans, finite
numbers, objects with string keys, arrays or slices, and nil. Unsupported
values, non-string map keys, non-finite floats, and cycles return
`ErrInvalidConfig` for profiles or `ErrInvalidRequest` for request
overrides.
2026-07-04 14:24:06 +00:00
2026-07-26 14:16:09 +00:00
## Profiles And Credentials
2026-07-04 14:24:06 +00:00
2026-07-26 14:16:09 +00:00
`OpenAICompatibleProfile(OpenAICompatibleProfileConfig)` creates an
in-memory `Profile` . Its public fields are `ID` , `Endpoint` , `Model` ,
`Temperature` , `MaxTokens` , `TopP` , `TimeoutSeconds` , `ServiceTier` ,
`ReasoningEffort` , `APIKeyRequired` , and `ExtraParams` .
`WithProfiles` rejects duplicate IDs in one call.
2026-07-05 03:09:32 +00:00
2026-07-26 14:16:09 +00:00
A direct `RunRequest.APIKey` is request-scoped and takes precedence over
`api_key_env` for the built-in client. It is excluded from JSON output and
from `PreparedRun` and `RunResult` . The package's `String` and
`GoString` methods report only whether a direct key is set. Do not use
reflection-based dumps of request structs, which can bypass that redaction.
2026-07-05 03:09:32 +00:00
2026-07-26 14:16:09 +00:00
## Injected LLM Clients
2026-07-05 03:09:32 +00:00
2026-07-26 14:16:09 +00:00
`LLMClient` implements:
2026-07-04 14:24:06 +00:00
```go
2026-07-26 14:16:09 +00:00
Generate(context.Context, GenerateRequest) (*GenerateResponse, error)
2026-07-04 14:24:06 +00:00
```
2026-07-26 14:16:09 +00:00
Injected clients receive the rendered prompt, effective execution target, numeric
target-presence metadata, optional structured-output specification, and direct
request API key. `GenerateResponse` returns content and `TokenUsage` .
Custom clients should avoid logging raw prompts or credentials.
2026-07-04 23:22:13 +00:00
2026-07-04 14:24:06 +00:00
## Errors
2026-07-26 14:16:09 +00:00
Public methods preserve these sentinel checks through `errors.Is` :
2026-07-04 14:24:06 +00:00
- `ErrInvalidConfig`
- `ErrInvalidRequest`
- `ErrPromptNotFound`
- `ErrProfileNotFound`
2026-07-28 00:35:54 +00:00
- `ErrProfileRequired`
2026-07-04 14:24:06 +00:00
- `ErrPromptLoad`
- `ErrProfileLoad`
2026-07-28 00:35:54 +00:00
- `ErrAPIKeyEnvMissing`
2026-07-04 14:24:06 +00:00
- `ErrArtifactLoad`
- `ErrPromptRender`
- `ErrLLMGenerate`
- `ErrValidation`
2026-07-26 14:16:09 +00:00
For interface selection and operational responsibilities, see the
[consumer integration overview ](api.md ).