304 lines
13 KiB
Markdown
304 lines
13 KiB
Markdown
# Framework Format Reference
|
|
|
|
## Purpose
|
|
|
|
This document is the canonical contract for Promptkit prompt-definition,
|
|
profile, and schema files. The [Go package consumer guide](consumers/pkg-promptkit.md)
|
|
explains how to select these sources and invoke the engine. The
|
|
[OpenAI-compatible integration contract](integrations/openai-compatible-chat.md)
|
|
owns the resulting outbound wire behavior.
|
|
|
|
Prompt and profile sources recursively discover files ending in `.yaml` or
|
|
`.yml`. YAML decoding is strict: unknown fields are errors for the selected
|
|
definition. Definitions are selected by their YAML `id`, not their file name
|
|
or directory.
|
|
|
|
## Prompt Definitions
|
|
|
|
A prompt definition describes inputs, Go-template messages, an optional
|
|
default profile, and an output contract.
|
|
|
|
```yaml
|
|
id: 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
|
|
```
|
|
|
|
| Field | Required | Meaning |
|
|
| --- | --- | --- |
|
|
| `id` | yes | Non-empty prompt identifier used by `RunRequest.PromptID`. |
|
|
| `version` | yes | Non-empty version selected by an optional `RunRequest.PromptVersion`. |
|
|
| `default_profile` | no | Non-empty profile ID used when the request omits `ProfileID`. |
|
|
| `description` | no | Human-readable description. |
|
|
| `session_id` | no | Go template rendered from request variables and input helpers. |
|
|
| `inputs` | no | Declared input metadata. |
|
|
| `messages` | yes | One or more chat-message templates. |
|
|
| `output` | yes | Output format and validation settings. |
|
|
|
|
When a request omits a version, the selected prompt ID must identify exactly
|
|
one definition. When it supplies a version, the ID and version pair must be
|
|
unique.
|
|
|
|
### Inputs
|
|
|
|
Each `inputs` item has these fields:
|
|
|
|
| Field | Required | Meaning |
|
|
| --- | --- | --- |
|
|
| `name` | yes | Non-empty name used by the request input map and `input` template helper. Names must be unique. |
|
|
| `required` | no | When true, preparation fails if the request omits the input. The default is false. |
|
|
| `content_type` | no | Expected media-type metadata. |
|
|
| `description` | no | Human-readable input description. |
|
|
|
|
Requests supply inputs as inline or file-backed `ArtifactRef` values. Declared
|
|
required inputs must be present. A template reference also requires the named
|
|
input to exist, whether or not it was declared. Extra request inputs are
|
|
allowed.
|
|
|
|
### Messages And Templates
|
|
|
|
Each message has a non-empty `role` and exactly one of:
|
|
|
|
- `content`, containing an inline Go template; or
|
|
- `content_file`, naming a file whose contents are the Go template.
|
|
|
|
For directory and `fs.FS` prompt sources, `content_file` resolves relative to
|
|
the prompt file and remains within the source root. `WithPromptFile` also
|
|
resolves it relative to that file.
|
|
|
|
Request variables are the template data, so a variable named `audience` is
|
|
referenced as `{{.audience}}`. The `{{input "note"}}` helper renders the body
|
|
of a named input. Missing variables and input references are errors.
|
|
|
|
The optional `session_id` uses the same template data and input helper. Its
|
|
rendered value is trimmed, omitted when empty, and limited to 256 Unicode code
|
|
points. A nonblank direct request session ID bypasses this template completely;
|
|
a blank direct value leaves the template behavior unchanged.
|
|
|
|
### Cache Control
|
|
|
|
`cache_control` is optional and has these fields:
|
|
|
|
| Field | Required | Values |
|
|
| --- | --- | --- |
|
|
| `type` | yes | `ephemeral` |
|
|
| `ttl` | no | Empty or `1h` |
|
|
|
|
Promptkit preserves cache-control metadata on the rendered message. The
|
|
outbound integration determines 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 to a schema in the configured schema source. |
|
|
| `repair_attempts` | no | Integer zero or greater; omitted means zero. |
|
|
|
|
The validation modes behave as follows:
|
|
|
|
- `none` skips content validation;
|
|
- `basic` requires non-empty generated content;
|
|
- `json` requires valid JSON; and
|
|
- `json_schema` requires valid JSON that satisfies the selected schema.
|
|
|
|
`format` controls output artifact metadata. JSON Schema mode also supplies the
|
|
schema to compatible model clients as structured-output metadata. The public
|
|
engine does not install an output repairer, so its validation is single-pass
|
|
even when a positive `repair_attempts` value is present.
|
|
|
|
A request-level `OutputContract` replaces the complete prompt output contract.
|
|
It does not merge individual fields. If its format is empty, Promptkit uses
|
|
`text`.
|
|
|
|
## Profile Definitions
|
|
|
|
A profile supplies model execution settings:
|
|
|
|
```yaml
|
|
id: local-summary
|
|
backend: openrouter
|
|
model: example-model
|
|
temperature: 0.2
|
|
max_tokens: 500
|
|
top_p: 0.95
|
|
timeout_seconds: 90
|
|
service_tier: flex
|
|
reasoning_effort: medium
|
|
extra_params:
|
|
provider_option: enabled
|
|
```
|
|
|
|
| Field | Required | Meaning |
|
|
| --- | --- | --- |
|
|
| `id` | yes | Non-empty profile identifier. IDs must be unique within one source. |
|
|
| `backend` | unless `endpoint` is present | Backend registry ID. It is trimmed and registry membership is checked when the profile is prepared or inspected. |
|
|
| `endpoint` | unless `backend` is present | Non-empty OpenAI-compatible base URL, including an API version path when required. When both connection fields are present, this overrides the backend endpoint without changing backend identity. |
|
|
| `model` | yes | Non-empty provider model name. |
|
|
| `temperature` | no | Number from 0 through 2. |
|
|
| `max_tokens` | no | Integer zero or greater. |
|
|
| `top_p` | no | Number from 0 through 1. |
|
|
| `timeout_seconds` | no | Per-generation deadline in whole seconds; integer zero or greater. |
|
|
| `service_tier` | no | Provider-specific request tier. |
|
|
| `reasoning_effort` | no | Provider-specific reasoning setting. |
|
|
| `api_key_env` | no | Name of an environment variable containing the API key. |
|
|
| `extra_params` | no | JSON-compatible provider-specific outbound fields. |
|
|
|
|
Raw `api_key` is prohibited in profile YAML. Store only an environment
|
|
variable name in `api_key_env`.
|
|
|
|
Promptkit does not infer a backend from a model or endpoint. Endpoint-only
|
|
profiles remain supported and have no effective backend ID.
|
|
The engine always provides the built-in `openrouter` ID. Consumers can add
|
|
engine-scoped IDs with
|
|
[`WithBackend`](../backends.go); exact registration validation belongs to its
|
|
GoDoc.
|
|
|
|
`extra_params` accepts null, booleans, finite numbers, strings, arrays, and
|
|
objects with string keys. Keys must be non-empty. With the built-in client,
|
|
they also cannot collide with the standard fields listed in the
|
|
[outbound request contract](integrations/openai-compatible-chat.md#request-body).
|
|
|
|
### Defaults And Overrides
|
|
|
|
Execution settings resolve in this order:
|
|
|
|
1. framework defaults;
|
|
2. the selected backend, when the profile names one;
|
|
3. the selected profile; and
|
|
4. request `ExecutionTargetOverride` values.
|
|
|
|
The framework defaults are:
|
|
|
|
| Setting | Default |
|
|
| --- | --- |
|
|
| `temperature` | `0` |
|
|
| `max_tokens` | `0` |
|
|
| `top_p` | `1` |
|
|
| `timeout_seconds` | `600` |
|
|
|
|
Numeric zero in a file or in-memory profile means that the profile does not
|
|
replace the framework default. Numeric request overrides use pointers, so an
|
|
explicit zero is preserved. In particular, an explicit request
|
|
`timeout_seconds` of zero disables the per-generation deadline while leaving
|
|
the caller context and transport timeout intact.
|
|
|
|
Non-empty profile strings replace backend defaults, and non-empty request
|
|
strings replace both. Request reasoning is the exception: a nil
|
|
`ReasoningEffort` pointer inherits the profile, a pointer to a nonblank string
|
|
trims and replaces it, and a pointer to a blank string clears it. Backend
|
|
identity is retained when either layer overrides the endpoint, so the override
|
|
also retains any engine-local capacity policy configured for that backend.
|
|
Capacity configuration belongs to the Go
|
|
[`Backend` API](../backends.go), not prompt or profile YAML. A non-empty
|
|
`extra_params` map at each layer replaces the entire lower-precedence map
|
|
rather than merging keys.
|
|
The [outbound integration contract](integrations/openai-compatible-chat.md)
|
|
defines how the effective settings are serialized.
|
|
|
|
### Source And Profile Precedence
|
|
|
|
An explicit request profile ID takes precedence over the prompt's
|
|
`default_profile`. If neither is present, preparation fails. Exact profile
|
|
inspection instead takes one explicit profile ID and does not use a prompt
|
|
default.
|
|
|
|
Profile sources resolve matching IDs in this order:
|
|
|
|
1. in-memory profiles supplied with `WithProfiles`;
|
|
2. a profile file, `fs.FS`, or configured profile directory; and
|
|
3. embedded built-in profiles.
|
|
|
|
A higher-precedence source falls back only when the profile is absent. An
|
|
invalid matching profile is an error and does not fall back. In-memory
|
|
`Profile` values follow the same ranges as YAML profiles. They use
|
|
`APIKeyRequired` for request-scoped credentials instead of `api_key_env`.
|
|
Preparation and exact profile inspection use this same source precedence.
|
|
|
|
## Built-In Profile Catalog
|
|
|
|
Every built-in selects the `openrouter` backend. The engine's built-in backend
|
|
registry supplies `https://openrouter.ai/api/v1` and the environment-variable
|
|
name `OPENROUTER_API_KEY`, so individual profiles contain only model and
|
|
generation settings. Built-in profile files do not repeat those connection
|
|
values. A custom or in-memory profile with the same profile ID takes
|
|
precedence.
|
|
|
|
| Provider | ID | Model |
|
|
| --- | --- | --- |
|
|
| aion-labs | `aion-2` | `aion-labs/aion-2.0` |
|
|
| anthropic | `claude-fable-latest` | `~anthropic/claude-fable-latest` |
|
|
| anthropic | `claude-haiku-latest` | `~anthropic/claude-haiku-latest` |
|
|
| anthropic | `claude-opus-latest` | `~anthropic/claude-opus-latest` |
|
|
| anthropic | `claude-sonnet-latest` | `~anthropic/claude-sonnet-latest` |
|
|
| deepseek | `deepseek-3-2` | `deepseek/deepseek-v3.2` |
|
|
| deepseek | `deepseek-4-flash` | `deepseek/deepseek-v4-flash` |
|
|
| deepseek | `deepseek-4-pro` | `deepseek/deepseek-v4-pro` |
|
|
| google | `gemini-2-flash` | `google/gemini-2.5-flash` |
|
|
| google | `gemini-2-flash-lite` | `google/gemini-2.5-flash-lite` |
|
|
| google | `gemini-2-pro` | `google/gemini-2.5-pro` |
|
|
| google | `gemini-3-flash-lite` | `google/gemini-3.1-flash-lite` |
|
|
| google | `gemini-flash-latest` | `~google/gemini-flash-latest` |
|
|
| google | `gemini-pro-latest` | `~google/gemini-pro-latest` |
|
|
| google | `gemma-4-31b` | `google/gemma-4-31b-it:exacto` |
|
|
| minimax | `minimax-m2` | `minimax/minimax-m2.5` |
|
|
| minimax | `minimax-m3` | `minimax/minimax-m3` |
|
|
| mistral | `mistral-large-2512` | `mistralai/mistral-large-2512` |
|
|
| mistral | `mistral-medium-3-5` | `mistralai/mistral-medium-3-5` |
|
|
| mistral | `mistral-small-3` | `mistralai/mistral-small-3.2-24b-instruct` |
|
|
| mistral | `mistral-small-4` | `mistralai/mistral-small-2603` |
|
|
| nvidia | `nemotron-3-ultra` | `nvidia/nemotron-3-ultra-550b-a55b` |
|
|
| openai | `gpt-5-mini` | `openai/gpt-5.4-mini` |
|
|
| openai | `gpt-5-nano` | `openai/gpt-5.4-nano` |
|
|
|
|
## Schemas
|
|
|
|
Schemas are JSON documents selected by a prompt or request
|
|
`schema_path`. For a directory or `fs.FS` source, paths resolve within the
|
|
configured source root. Referenced nested schemas resolve relative to the
|
|
owning schema document. `WithSchemaFile` exposes one schema, addressed by its
|
|
base name.
|
|
|
|
An unreadable, invalid, or unresolvable schema produces an operational
|
|
validation error. Generated content that is valid JSON but does not satisfy the
|
|
schema produces a failed validation result.
|
|
|
|
## Credentials
|
|
|
|
Credential values belong at the request or environment boundary, never in
|
|
prompt, profile, schema, or example files:
|
|
|
|
- a file profile names an environment variable with `api_key_env`;
|
|
- an in-memory profile may set `APIKeyRequired`;
|
|
- a request can provide a direct `APIKey` or override `APIKeyEnv`; and
|
|
- a direct request key takes precedence over environment lookup.
|
|
|
|
After a direct request key, the credential-source precedence is request
|
|
`APIKeyEnv`, profile `api_key_env`, then the backend default. An in-memory
|
|
profile with `APIKeyRequired` clears an inherited backend environment name and
|
|
requires a direct key unless the request explicitly supplies `APIKeyEnv`.
|
|
Promptkit validates required credential availability during preparation.
|
|
Direct keys are excluded from JSON results and redacted by public string
|
|
formatters. Environment-variable names may appear in prepared metadata, but
|
|
their values do not.
|