# Package `scriptorium` Import path: ```go import "gitea.maximumdirect.net/eric/scriptorium" ``` 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). ## Engine Construction `NewEngine(Config, ...Option)` constructs an engine. `Config` has these fields: | Field | Meaning | | --- | --- | | `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 `.`. | | `Timeout` | Base timeout for the built-in OpenAI-compatible client when `HTTPClient` is absent or has a zero timeout. A non-positive value uses the internal default. | | `HTTPClient` | Optional HTTP client for that built-in client. It is cloned; a non-zero `Timeout` on it takes precedence over `Config.Timeout` as the base timeout. | Nil options are ignored. Invalid construction, including `WithLLMClient(nil)`, returns an error matching `ErrInvalidConfig`. An effective positive `timeout_seconds` replaces the base timeout. An explicit request override of zero disables the HTTP-client timeout. The timeout is otherwise inherited from the supplied client, `Config.Timeout`, or the internal default in that order. Source options replace their matching directory source: - prompts: `WithPromptFS(fsys, root)`, `WithPromptFile(path)`; - profiles: `WithProfileFS(fsys, root)`, `WithProfileFile(path)`, and `WithProfiles(profiles...)`; - schemas: `WithSchemaFS(fsys, root)`, `WithSchemaFile(path)`; and - LLM client: `WithLLMClient(client)`. `fs.FS` prompt-content and schema paths stay inside their configured roots. 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). ## Prepare And Run `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. ```go engine, err := scriptorium.NewEngine(scriptorium.Config{ PromptDir: "./examples/prompts", ProfileDir: "./examples/profiles", }) if err != nil { return err } 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 } _ = prepared.Messages ``` The maintained package example is [`examples/go-library/prepare`](../../examples/go-library/prepare). `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. `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`. ## Public Values `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. The exported constants define these serialized values: - 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`. `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. ## Requests, Inputs, And Overrides `RunRequest` fields are `PromptID`, `PromptVersion`, `ProfileID`, `APIKey`, `Inputs`, `Vars`, `Execution`, `Validation`, and `Metadata`. Input helpers are: - `File(path)` for a file-backed artifact; - `Inline(body)` for inline content; and - `InlineWithURI(uri, body)` for inline content with URI metadata. 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. `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`. `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. ## Profiles And Credentials `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. 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. ## Injected LLM Clients `LLMClient` implements: ```go Generate(context.Context, GenerateRequest) (*GenerateResponse, error) ``` 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. ## Errors Public methods preserve these sentinel checks through `errors.Is`: - `ErrInvalidConfig` - `ErrInvalidRequest` - `ErrPromptNotFound` - `ErrProfileNotFound` - `ErrPromptLoad` - `ErrProfileLoad` - `ErrArtifactLoad` - `ErrPromptRender` - `ErrLLMGenerate` - `ErrValidation` For interface selection and operational responsibilities, see the [consumer integration overview](api.md).