392 lines
19 KiB
Markdown
392 lines
19 KiB
Markdown
# Framework Format Reference
|
||
|
||
## Purpose
|
||
|
||
This is the canonical reference for Promptkit's backend, profile, prompt, and
|
||
schema definitions. The [Go consumer guide](consumers/pkg-promptkit.md) shows
|
||
how to select sources and use an engine; the
|
||
[OpenAI-compatible integration contract](integrations/openai-compatible-chat.md)
|
||
owns outbound wire behavior. [ConfigKit](https://gitea.maximumdirect.net/eric/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 may contain keyed top-level `backends`, `profiles`,
|
||
and `prompts` mappings, plus a `collections` mapping of namespaced resource
|
||
groups. Resource keys are literal IDs, not filename-derived identities. Each
|
||
prompt ID maps directly to one definition; an optional `version` string is
|
||
descriptive metadata, not a selection key. Keys and references must be nonblank
|
||
and remain exact: Promptkit does not trim or re-key them. Old embedded `id` and
|
||
`base_profile` fields are invalid. Unknown fields are errors. Promptkit installs
|
||
no provider or profile catalog; callers select the definitions they need.
|
||
|
||
```yaml
|
||
backends:
|
||
local:
|
||
endpoint: http://localhost:8000/v1
|
||
concurrency_limit: 2
|
||
profiles:
|
||
local-summary:
|
||
backend: local
|
||
model: example-model
|
||
prompts:
|
||
meeting.summary:
|
||
version: "1.0.0"
|
||
default_profile: local-summary
|
||
messages:
|
||
- role: user
|
||
content: Summarize this note.
|
||
output:
|
||
format: text
|
||
validation_mode: none
|
||
collections:
|
||
support:
|
||
release_version: "1.4.0"
|
||
backends:
|
||
offline:
|
||
endpoint: https://example.invalid/v1
|
||
profiles:
|
||
base:
|
||
backend: support/offline
|
||
model: offline-model
|
||
fast:
|
||
extends: base
|
||
timeout_seconds: 30
|
||
prompts:
|
||
answer:
|
||
default_profile: support/fast
|
||
messages:
|
||
- role: user
|
||
content: Answer the selected caller input.
|
||
output:
|
||
format: text
|
||
validation_mode: none
|
||
```
|
||
|
||
## Source Headers, Collections, And Resource IDs
|
||
|
||
An input may omit a source header. When present, the source-root `version` is
|
||
reserved for ConfigKit's specification header and accepts only the exact string
|
||
`"1"` or strict decimal integer `1`; null and other values are invalid. This
|
||
header is distinct from a prompt's nested `version` label and a collection's
|
||
`release_version`. ConfigKit checks and consumes accepted headers on non-main
|
||
inputs; a declaration on the main input remains visible in explicit
|
||
configuration inspection. Headerless inputs still undergo ordinary final-value
|
||
validation. ConfigKit owns generic import and source-history behavior.
|
||
|
||
The root resource mappings contain unqualified IDs. Each `collections` entry
|
||
has a namespace key and may contain `release_version` plus the same three
|
||
resource mappings. Collection resource keys are local keys; their runtime IDs
|
||
are `<namespace>/<local-key>`. Root and collection keys may be the same. A
|
||
namespace and local key must be nonblank and slash-free, and references must
|
||
name their intended exact ID; mounting a source does not rewrite references.
|
||
For example, the `support/fast` profile above stores `support/offline` as its
|
||
backend ID. In `collections.support.profiles.fast`, ConfigKit `extends: base`
|
||
refers to a sibling profile in that same mapping. It is not a qualified or
|
||
cross-collection reference.
|
||
|
||
`release_version` and prompt `version` are optional opaque labels. Absent or
|
||
null means no label; an explicitly empty string is retained as a declared
|
||
label. Neither label selects a resource or changes execution. Runtime lookups
|
||
use the captured effective resource indexes. `InspectConfiguration` is an
|
||
explicit operator view of effective settings and provenance; source history is
|
||
not a second runtime resolver, and the retained effective shape is not flattened
|
||
or rewritten into those indexes.
|
||
|
||
For examples of explicitly selecting native collection inputs and inspecting
|
||
inventories, see the [consumer guide](consumers/pkg-promptkit.md) and its
|
||
[maintained preparation example](../examples/go-library/prepare/main.go). For
|
||
breaking identity and prompt-selection changes, see the
|
||
[configuration migration guide](consumers/configuration-migration.md).
|
||
|
||
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 [resource and collection listing](consumers/pkg-promptkit.md#discover-available-resources-and-collections).
|
||
|
||
## Prompt Definitions
|
||
|
||
The `prompts` mapping selects a literal prompt ID whose value is the definition:
|
||
|
||
```yaml
|
||
prompts:
|
||
meeting.summary:
|
||
version: "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. `InspectPrompt` selects the same captured definition 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](consumers/pkg-promptkit.md#inspect-requirements-before-preparation) and
|
||
the method's [GoDoc](../requirements.go) 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`.
|
||
|
||
## Backend Definitions
|
||
|
||
Backend definitions are supplied through caller-selected configuration
|
||
sources. The conventional backend IDs are names only; PromptKit does not
|
||
install definitions for them.
|
||
|
||
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`:
|
||
|
||
```yaml
|
||
backends:
|
||
openrouter:
|
||
smoke_tests:
|
||
default_profile: application-profile
|
||
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 an inference diagnostic selects that default. Omitted/null
|
||
`default_profile` means there is no inference 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 (`openrouter_key` appends
|
||
`/key` to the effective backend base); an explicit endpoint follows the same
|
||
full-URL rules as reachability. `none` declares authentication inapplicable.
|
||
These values are configuration only: engine construction does not contact a
|
||
backend.
|
||
|
||
These fields are resolved through the ordinary ConfigKit source layers before
|
||
Promptkit validates the final effective values. A higher-priority mapping can
|
||
override individual nested fields; an explicit null can clear the whole
|
||
`smoke_tests` block or one of its nested objects. An endpoint set to null uses
|
||
its documented fallback, while an explicit blank endpoint is invalid. The
|
||
metadata does not change ordinary generation credential requirements or
|
||
provider settings.
|
||
|
||
## Profile Definitions
|
||
|
||
Profiles are keyed by literal ID and may inherit a named parent with
|
||
`extends`:
|
||
|
||
```yaml
|
||
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](integrations/openai-compatible-chat.md#request-body).
|
||
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](../types.go).
|
||
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 caller underlays in their given order, followed by an
|
||
optional main input. Later layers 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.
|
||
|
||
Root backends, profiles, and prompts, as well as collection declarations and
|
||
their resource mappings, follow these same source rules. `CollectionInput`
|
||
mounts one explicitly selected source at a collection destination and enables
|
||
ConfigKit imports for that input; it does not discover or select sources.
|
||
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 a sibling profile by local key in the same root or collection
|
||
mapping; collection inheritance cannot cross namespaces. Presence, explicit
|
||
null, and recursively merged maps determine the final fields. Other resource
|
||
references are exact IDs and use their qualified form when they select a
|
||
collection resource. 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](https://gitea.maximumdirect.net/eric/ConfigKit).
|
||
|
||
## 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.
|