Files
promptkit/docs/formats.md

17 KiB
Raw Blame History

Framework Format Reference

Purpose

This is the canonical reference for Promptkit's backend, profile, prompt, and schema definitions. The Go consumer guide shows how to select sources and use an engine; the OpenAI-compatible integration contract owns outbound wire behavior. ConfigKit owns the generic YAML grammar, imports, layering, inheritance, and diagnostics. This reference describes what Promptkit does with the final effective values.

A configuration document has keyed top-level backends, profiles, and prompts mappings. Their keys are literal IDs, not filename-derived identities. Prompt versions are a second keyed mapping. Keys and references must be nonblank and remain exact: Promptkit does not trim or re-key them. Old embedded id, version, and base_profile fields are invalid. Unknown fields are errors.

backends:
  local:
    endpoint: http://localhost:8000/v1
    concurrency_limit: 2
profiles:
  local-summary:
    backend: local
    model: example-model
prompts:
  meeting.summary:
    "1.0.0":
      default_profile: local-summary
      messages:
        - role: user
          content: Summarize this note.
      output:
        format: text
        validation_mode: none

Every effective backend, profile, and prompt definition is validated when NewEngine constructs the engine, even if it is never selected. A profile may be partial: an endpoint and model need only be complete after request overrides are applied. A prompt's default profile similarly need not be runnable without an overriding request. Missing request data, artifacts, schemas, credentials, and provider work remain runtime concerns.

The engine captures effective definitions, referenced message-file contents, and static template syntax at construction. It does not reread configuration or message files on ordinary runs; construct a new engine to observe edits. Schema and request artifact reads still happen during preparation. Use InspectConfiguration for an explicit effective-configuration or provenance report, InspectProfile for backend-completed profile settings, and preparation for request-specific rendered details. For identity discovery before inspection, see the consumer guide's profile and prompt listing.

Prompt Definitions

The prompts mapping selects a literal prompt ID, then a string version key:

prompts:
  meeting.summary:
    "1.0.0":
      default_profile: local-summary
      description: Summarize a synthetic meeting note.
      session_id: '{{.session}}'
      inputs:
        - name: note
          required: true
          content_type: text/plain
          description: Meeting note to summarize.
      messages:
        - role: system
          content: Return a concise summary.
          cache_control:
            type: ephemeral
            ttl: 1h
        - role: user
          content_file: ./summary.user.md
      output:
        format: markdown
        validation_mode: basic
        repair_attempts: 0

messages must be nonempty and output must be a valid mapping. Optional default_profile, description, session_id, inputs, and cache-control fields may be absent or cleared with null where appropriate. A null whole definition, required role, output format, or validation mode is invalid. required and repair_attempts default to false and zero, respectively, and are not nullable. A request that omits a prompt version succeeds only if that prompt ID has exactly one effective version. InspectPrompt selects from the same captured definitions without rendering or resolving a profile.

Inputs

Each inputs item may contain name, required, content_type, and description. name is required, nonblank, and unique within the prompt. Omitted required means false. Null inputs means no declarations. Requests supply inline or file-backed ArtifactRef values; declared required inputs must be present. A template reference also needs its named input, even when undeclared. Extra request inputs are allowed.

Messages And Templates

Each message needs a role and exactly one nonnull content or content_file. An explicitly empty inline content is valid. Null clears either content selection. Roles are trimmed and lowercased, then must be developer, system, user, or assistant. Static template syntax is checked during construction; missing variables and named inputs fail when rendered. Request variables are template data ({{.audience}}), and {{input "note"}} renders an input body.

content_file uses the effective field's own source context, including when inherited or imported. Its relative path is resolved against that source's base directory within its rooted filesystem. Absolute paths and lexical escapes from the selected root fail. Host-file sources also prevent symlink escapes. Promptkit preserves the path text, including meaningful whitespace, after checking that it is not blank. A source without a unique usable resource context must supply one explicitly or override the field. Content is captured at construction, not reopened for each request.

Optional session_id uses the same template variables and input helper. Its rendered value is trimmed, omitted if empty, and limited to 256 Unicode code points. A nonblank direct request session ID bypasses the template.

InspectRequirements can enumerate recognizable dependencies from captured templates before artifact content is available. Its conservative syntax coverage does not change template validity or rendering; see the consumer guide and the method's GoDoc for that inspection boundary.

Cache Control

Optional cache_control has required type: ephemeral and optional ttl, which may be empty or 1h. Promptkit retains this metadata on rendered messages; the integration contract defines its wire representation.

Output Contract

Field Required Values or behavior
format yes text, markdown, or json
validation_mode yes none, basic, json, or json_schema
schema_path for json_schema Path in the selected schema source
repair_attempts no Integer 0–3; default 0. Positive values need basic, json, or json_schema

none skips content validation; basic requires nonempty content; json accepts any valid JSON value; json_schema checks the selected schema. format determines output artifact metadata. JSON Schema mode also supplies structured-output metadata to compatible clients. Plain json does not request a provider-native JSON-object constraint. A positive repair budget counts additional generations after failed validation; exhaustion returns the last candidate and its failed validation result. Operational errors remain errors. A request-level OutputContract replaces the whole configured one, not individual fields; an empty request format defaults to text.

Built-In Backends

The selected catalog modules contribute these backend definitions as the earliest underlay. Their settings can be overlaid by caller sources; these IDs are not reserved against configuration changes.

ID Catalog endpoint API-key environment name Active generation limit
openrouter https://openrouter.ai/api/v1 OPENROUTER_API_KEY 16
rakestrawhome https://inference.ai.rakestrawhome.com/v1 RAKESTRAWHOME_INFERENCE_API_KEY 4

A backend definition may have endpoint, api_key_env, concurrency_limit, queue_capacity, extra_params, and smoke_tests. The final endpoint is required and must be an absolute HTTP(S) URL with a host, no user information, query, or fragment. An omitted or null API-key environment name means no lookup. Omitted/null concurrency is zero (unlimited); a supplied negative value is invalid. For positive concurrency, omitted/null queue capacity defaults to 1024. An explicit queue capacity, including zero, requires positive concurrency and must be nonnegative. Unlimited concurrency has no queue. Provider maps contain JSON-compatible values; null entries are ordinary JSON null. Unknown fields, including a raw api_key, fail.

smoke_tests is optional backend metadata for explicit diagnostic operations. It may contain default_profile, reachability, and authentication:

backends:
  openrouter:
    smoke_tests:
      default_profile: promptkit-openrouter-standard
      reachability:
        endpoint: https://status.example/ready?check=1
      authentication:
        kind: openrouter_key
        endpoint: https://openrouter.ai/api/v1/key

An omitted or null smoke_tests block disables these metadata defaults. default_profile is preserved as an exact, nonblank profile ID; its existence is checked only if a diagnostic selects that default. Omitted/null reachability or its endpoint uses the effective backend endpoint. An explicit reachability endpoint is trimmed and must be an absolute HTTP(S) URL with a host; unlike the backend base endpoint, its path and query are allowed. Null means fallback, while an explicit blank value is invalid.

Omitted/null authentication means no authentication adapter is declared. A non-null object requires kind, which is trimmed and case-normalized; the recognized values are none and openrouter_key. Its omitted/null endpoint uses the adapter's backend-relative destination; an explicit endpoint follows the same full-URL rules as reachability. These values are configuration only: engine construction does not contact a backend.

Profile Definitions

Profiles are keyed by literal ID and may inherit a named parent with extends:

profiles:
  local-summary:
    backend: local
    model: example-model
    temperature: 0.2
    max_tokens: 500
    timeout_seconds: 90
    extra_params:
      provider_option: enabled
  local-summary-fast:
    extends: local-summary
    timeout_seconds: 30
    reasoning_effort: low

Profiles may also supply endpoint, top_p, service_tier, api_key_env, and api_key_required. Promptkit does not infer a backend from an endpoint or model. A profile with only an endpoint has no backend capacity identity. Nonblank endpoints follow the backend URL rules; temperature is 0–2, top_p is 0–1, max_tokens and timeout_seconds are nonnegative. Provider maps accept JSON-compatible values with nonempty keys and cannot collide with the built-in client's standard request fields. Credential values do not belong in profiles: raw api_key is invalid.

Defaults And Overrides

After effective profile inheritance, Promptkit applies the selected backend's defaults once, then request ExecutionTargetOverride values. Backend-derived settings are not inheritance input: changing a child profile's backend does not carry the parent's derived endpoint or credential source into it. Changing only a model or backend does not clear unrelated explicitly inherited fields.

Profile field Absent Explicit value Explicit null
backend No backend Exact backend ID; blank means none No backend
endpoint Selected backend endpoint Valid nonblank URL; empty clears Clear, without backend fallback
model Unspecified Nonblank model; empty clears Unspecified
temperature, top_p, max_tokens Unspecified Valid value, including outbound zero Suppress outbound control
service_tier, reasoning_effort Unspecified Normalized value; blank suppresses Suppress outbound control
timeout_seconds 600 seconds Nonnegative; zero disables generation deadline Reset to 600 seconds
api_key_env Backend lookup name, if any Trimmed name; blank disables Disable backend lookup
api_key_required False Boolean, including false False
extra_params Backend defaults Recursively overlay profile map on backend map Suppress configured provider map

An empty mapping does not clear inherited map entries; null clears the whole map. Nested maps merge recursively, while scalar and array values replace. Runtime nonempty ExtraParams overrides replace the entire configured map. Request overrides otherwise follow the public value GoDoc. For example, a runtime extra_params["extends"] key is ordinary provider data, not a configuration inheritance instruction. An explicit zero timeout does not disable the caller context or HTTP transport timeout.

Source And Profile Precedence

NewEngine composes catalog definitions first, Promptkit-owned definitions next, then caller underlays in their given order, with an optional main input last. Later tiers overlay earlier ones. Inputs within one underlay group are strictly composed: conflicting contributions are errors, not priority signals. The directory helpers discover .yaml and .yml files recursively in sorted order, but that order does not give one file higher precedence. An explicitly selected missing/unreadable root fails; an empty root contributes nothing. Imports are disabled by these helpers unless the caller enables them on an input. Single files can use ConfigKit inputs directly.

Backends, profiles, and prompts all follow these same source rules. A later profile or backend can change individual fields of a lower definition. A request ProfileID takes precedence over a prompt default_profile; if neither is selected, preparation fails. Exact profile inspection selects one explicit ID and does not consult a prompt default.

Profile Inheritance

ConfigKit resolves extends on effective profile definitions. One profile may inherit another keyed profile; presence, explicit null, and recursively merged maps determine the final fields. References are literal IDs, including IDs containing punctuation. There is no Promptkit-specific depth limit or second base-chain resolver. Missing references and cycles fail at construction. For generic inheritance and layer mechanics, consult ConfigKit.

Built-In Profile Catalog

Promptkit contributes two opt-in definitions; neither is selected by default:

ID Current definition
promptkit-openrouter-standard Extends the selected OpenRouter catalog's gemini-flash-latest profile.
promptkit-openrouter-auto Selects backend openrouter and model openrouter/auto.

Select one through request ProfileID or prompt default_profile. Caller layers may overlay these definitions or their catalog bases. The release policy owns their cross-version compatibility boundary.

External Profile Inventories

The selected catalog modules, not this document, own their profile inventories:

These are tested local data, not a promise of live provider availability. The release policy owns the compatibility boundary.

Schemas

Schemas are JSON documents selected by a prompt or request schema_path. Directory and fs.FS schema paths resolve within the configured root; referenced nested schemas resolve relative to the owning schema document. WithSchemaFile exposes one schema under its base name. An unreadable, invalid, or unresolvable schema causes an operational validation error. Valid JSON that fails the schema instead yields a failed validation result.

Credentials

Only environment-variable names belong in backend/profile definitions, never credential values. A request may supply a direct APIKey or an APIKeyEnv override. A direct key takes precedence, followed by a request environment source, an explicit profile source, and an inherited backend source. A true profile api_key_required suppresses the backend-derived environment source, but an explicit profile or request environment source remains usable. False restores ordinary optional-credential behavior. Missing or blank optional environment values leave the built-in client's Authorization header absent; required availability is checked at preparation and again during prepared execution. Injected clients own their credential-resolution behavior.

Credential values are excluded from JSON results and redacted by public string formatters. ConfigKit inspection redacts credential-shaped dynamic provider keys, but does not make arbitrary prompt/provider content safe to disclose. Applications own report disclosure and secret handling.