2026-07-28 04:53:51 +00:00
|
|
|
|
# Framework Format Reference
|
|
|
|
|
|
|
|
|
|
|
|
## Purpose
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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
|
2026-07-28 04:53:51 +00:00
|
|
|
|
[OpenAI-compatible integration contract](integrations/openai-compatible-chat.md)
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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.
|
2026-07-28 04:53:51 +00:00
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
|
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.
|
2026-07-28 04:53:51 +00:00
|
|
|
|
|
|
|
|
|
|
## Prompt Definitions
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
The `prompts` mapping selects a literal prompt ID, then a string version key:
|
2026-07-28 04:53:51 +00:00
|
|
|
|
|
|
|
|
|
|
```yaml
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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
|
2026-07-28 04:53:51 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
`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.
|
2026-07-30 21:06:33 +00:00
|
|
|
|
|
2026-07-28 04:53:51 +00:00
|
|
|
|
### Inputs
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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.
|
2026-07-28 04:53:51 +00:00
|
|
|
|
|
|
|
|
|
|
### Messages And Templates
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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.
|
2026-07-28 04:53:51 +00:00
|
|
|
|
|
2026-10-08 20:48:10 +00:00
|
|
|
|
`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.
|
|
|
|
|
|
|
2026-07-28 04:53:51 +00:00
|
|
|
|
### Cache Control
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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.
|
2026-07-28 04:53:51 +00:00
|
|
|
|
|
|
|
|
|
|
### Output Contract
|
|
|
|
|
|
|
|
|
|
|
|
| Field | Required | Values or behavior |
|
|
|
|
|
|
| --- | --- | --- |
|
2026-09-30 03:34:15 +00:00
|
|
|
|
| `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`.
|
2026-07-28 04:53:51 +00:00
|
|
|
|
|
2026-08-23 17:19:12 +00:00
|
|
|
|
## Built-In Backends
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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`, and `extra_params`. 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.
|
2026-08-23 17:19:12 +00:00
|
|
|
|
|
2026-07-28 04:53:51 +00:00
|
|
|
|
## Profile Definitions
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
Profiles are keyed by literal ID and may inherit a named parent with
|
|
|
|
|
|
`extends`:
|
2026-08-25 01:46:16 +00:00
|
|
|
|
|
|
|
|
|
|
```yaml
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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
|
2026-08-25 01:46:16 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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.
|
2026-07-28 04:53:51 +00:00
|
|
|
|
|
|
|
|
|
|
### Defaults And Overrides
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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.
|
2026-07-28 04:53:51 +00:00
|
|
|
|
|
|
|
|
|
|
### Source And Profile Precedence
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
`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.
|
2026-08-25 01:46:16 +00:00
|
|
|
|
|
|
|
|
|
|
### Profile Inheritance
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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](https://gitea.maximumdirect.net/eric/ConfigKit).
|
2026-08-25 01:46:16 +00:00
|
|
|
|
|
2026-07-28 04:53:51 +00:00
|
|
|
|
## Built-In Profile Catalog
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
Promptkit contributes two opt-in definitions; neither is selected by default:
|
2026-09-22 12:23:07 +00:00
|
|
|
|
|
|
|
|
|
|
| ID | Current definition |
|
|
|
|
|
|
| --- | --- |
|
2026-09-30 03:34:15 +00:00
|
|
|
|
| `promptkit-openrouter-standard` | Extends the selected OpenRouter catalog's `gemini-flash-latest` profile. |
|
2026-09-22 12:23:07 +00:00
|
|
|
|
| `promptkit-openrouter-auto` | Selects backend `openrouter` and model `openrouter/auto`. |
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
Select one through request `ProfileID` or prompt `default_profile`.
|
|
|
|
|
|
Caller layers may overlay these definitions or their catalog bases. The
|
|
|
|
|
|
[release policy](policy/release.md#catalog-profile-compatibility) owns their
|
|
|
|
|
|
cross-version compatibility boundary.
|
2026-09-22 12:31:50 +00:00
|
|
|
|
|
|
|
|
|
|
## External Profile Inventories
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
The selected catalog modules, not this document, own their profile inventories:
|
2026-09-22 12:31:50 +00:00
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
- [OpenRouter catalog v3.20260930.0 profiles](https://gitea.maximumdirect.net/eric/promptkit-backend-openrouter/src/tag/v3.20260930.0/catalog/profiles)
|
|
|
|
|
|
- [Rakestrawhome catalog v3.20260930.0 profiles](https://gitea.maximumdirect.net/eric/promptkit-backend-rakestrawhome/src/tag/v3.20260930.0/catalog/profiles)
|
2026-09-22 12:31:50 +00:00
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
These are tested local data, not a promise of live provider availability.
|
|
|
|
|
|
The [release policy](policy/release.md#catalog-profile-compatibility) owns
|
|
|
|
|
|
the compatibility boundary.
|
2026-07-28 04:53:51 +00:00
|
|
|
|
|
|
|
|
|
|
## Schemas
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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.
|
2026-07-28 04:53:51 +00:00
|
|
|
|
|
|
|
|
|
|
## Credentials
|
|
|
|
|
|
|
2026-09-30 03:34:15 +00:00
|
|
|
|
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.
|