Files
promptkit/docs/consumers/pkg-promptkit.md

6.6 KiB

Package promptkit

Import path:

import "gitea.maximumdirect.net/eric/promptkit"

Package promptkit is the supported Go contract for in-process prompt preparation and execution. The declarations and their GoDoc in the root package own the exact API; this guide explains how the pieces are used together.

Engine Construction And Sources

Construct an engine with NewEngine, Config, and Option. PromptDir is required unless a prompt source option is supplied. ProfileDir optionally overlays built-in profiles, and an empty SchemaDir uses the current directory. Timeout is the transport-wide safety cap for the built-in OpenAI-compatible client. An optional HTTPClient is cloned; its positive timeout takes precedence.

Nil options are ignored. Invalid construction, including a nil injected client or artifact reader, returns an error matching ErrInvalidConfig.

The source options replace their matching directory source:

  • WithPromptFS and WithPromptFile select prompt definitions;
  • WithProfileFS and WithProfileFile overlay built-in profiles;
  • WithProfiles adds in-memory profiles ahead of file and built-in profiles;
  • WithSchemaFS and WithSchemaFile select JSON Schema documents;
  • WithLLMClient replaces the built-in model client; and
  • WithArtifactReader replaces the default reader for every input.

Prompt-content and schema paths from an fs.FS stay within the configured root. Single-file prompt and profile sources select definitions by YAML ID. Relative prompt content resolves from its prompt file, while a single schema is addressed by its base name.

Per-generation timeout values from profiles or requests are independent of the transport cap and caller context. An explicit request value of zero disables only the per-generation deadline. The outbound integration contract defines the complete timeout layering.

Preparation And Execution

Engine.Prepare and Engine.Run accept the public RunRequest. Prepare resolves the prompt, profile, input artifacts, validation contract, and rendered messages without calling an LLM. Run performs the same preparation, calls the configured client, and validates the generated content.

engine, err := promptkit.NewEngine(promptkit.Config{
	PromptDir:  "./prompts",
	ProfileDir: "./profiles",
})
if err != nil {
	return err
}

prepared, err := engine.Prepare(ctx, promptkit.RunRequest{
	PromptID: "meeting.summary",
	Inputs: map[string]promptkit.ArtifactRef{
		"transcript": promptkit.File("./transcript.md"),
	},
})
if err != nil {
	return err
}
_ = prepared.Messages

PreparedRun and RunResult expose copied public values. Preparation returns effective settings, hashes, rendered messages, selected profile, structured-output information, and timing without resolved secrets or model output. Execution adds the generated artifact and raw output, validation state, model metadata, usage, run ID, and duration.

A generated-content validation failure returns a result with Validation.Status == ValidationFailed. An inability to perform validation returns an error matching ErrValidation.

Requests, Inputs, And Overrides

The request and value declarations own the available fields, serialized constants, and result shapes. Use File, Inline, or InlineWithURI to construct artifact references. Required declared inputs and every input referenced by a template must be supplied.

ExecutionTargetOverride uses pointers for numeric settings so an explicit zero remains distinct from no override. ExtraParams accepts JSON-compatible strings, booleans, finite numbers, string-keyed objects, arrays or slices, and nil. Unsupported values, non-string map keys, non-finite numbers, and cycles match ErrInvalidConfig in profiles or ErrInvalidRequest in request overrides.

Returned requests, profiles, prepared values, results, artifacts, maps, and slices are isolated from internal engine state. Consumers and injected extensions should not retain or mutate values owned by another caller.

Profiles And Credentials

OpenAICompatibleProfile constructs an ordinary in-memory profile for an OpenAI-compatible chat-completions endpoint. WithProfiles rejects duplicate IDs in one call and gives in-memory profiles precedence over explicit file sources and built-ins.

Raw API keys do not belong in profiles. File-backed profiles may name an environment variable, while an in-memory profile can require a request key. A direct RunRequest.APIKey is request-scoped and takes precedence over an environment lookup for the built-in client.

API keys are excluded from JSON, prepared values, and results. The public String and GoString methods report only whether a direct key is present. Avoid reflection-based dumps of request structs, which can bypass that redaction.

Extension Interfaces

The LLMClient, GenerateRequest, and GenerateResponse boundary lets a consumer replace model generation. Injected clients receive copied rendered messages, effective settings, explicit numeric-setting presence, structured-output constraints, and the request-scoped key. They return generated content and token usage.

The ArtifactReader boundary replaces the default inline and file reader for every input. Readers provide artifact content and metadata; the engine fills an empty artifact name from the input-map key. A reader error matches ErrArtifactLoad while preserving the original identity for errors.Is. A nil artifact with a nil error is also an artifact-load failure.

Extensions should honor context cancellation and avoid logging raw prompts, artifacts, or credentials.

Errors

The public error declarations and mapping preserve these sentinel checks through errors.Is:

  • ErrInvalidConfig
  • ErrInvalidRequest
  • ErrPromptNotFound
  • ErrProfileNotFound
  • ErrProfileRequired
  • ErrPromptLoad
  • ErrProfileLoad
  • ErrAPIKeyEnvMissing
  • ErrArtifactLoad
  • ErrPromptRender
  • ErrLLMGenerate
  • ErrValidation

ErrProfileRequired and ErrAPIKeyEnvMissing also match ErrInvalidRequest, allowing either broad request handling or a specific condition. Wrapped collaborator errors retain their identity where the public contract promises it.

Consumer Boundary

Promptkit is an importable library. It does not own a command, inbound HTTP API, process configuration, or deployment policy. Scriptorium is one downstream application that maps this root package contract into those application concerns.