348 lines
17 KiB
Markdown
348 lines
17 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 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. For identity discovery before inspection,
|
||
see the consumer guide's [profile and prompt listing](consumers/pkg-promptkit.md#discover-available-profiles-and-prompts).
|
||
|
||
## Prompt Definitions
|
||
|
||
The `prompts` mapping selects a literal prompt ID, then a string version key:
|
||
|
||
```yaml
|
||
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](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`.
|
||
|
||
## 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`:
|
||
|
||
```yaml
|
||
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`:
|
||
|
||
```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 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](https://gitea.maximumdirect.net/eric/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](policy/release.md#catalog-profile-compatibility) owns their
|
||
cross-version compatibility boundary.
|
||
|
||
## External Profile Inventories
|
||
|
||
The selected catalog modules, not this document, own their profile inventories:
|
||
|
||
- [OpenRouter catalog v3.20261013.0 profiles](https://gitea.maximumdirect.net/eric/promptkit-backend-openrouter/src/tag/v3.20261013.0/catalog/profiles)
|
||
- [Rakestrawhome catalog v3.20261013.0 profiles](https://gitea.maximumdirect.net/eric/promptkit-backend-rakestrawhome/src/tag/v3.20261013.0/catalog/profiles)
|
||
|
||
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.
|
||
|
||
## 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.
|