Document appended request messages
This commit is contained in:
@@ -196,6 +196,26 @@ validity is not evidence of factual or domain correctness. See the
|
||||
[`OutputContract` GoDoc](../../types.go) for the exact budget and eligibility
|
||||
rules.
|
||||
|
||||
### Append Already-Rendered Messages
|
||||
|
||||
An application can include an earlier assistant response and its own corrective
|
||||
instruction in a fresh request without changing the configured prompt:
|
||||
|
||||
```go
|
||||
request.AppendedMessages = []promptkit.RenderedMessage{
|
||||
{Role: promptkit.RoleAssistant, Content: previousResponse},
|
||||
{Role: promptkit.RoleUser, Content: correction},
|
||||
}
|
||||
result, err := engine.Run(ctx, request)
|
||||
```
|
||||
|
||||
These messages are already rendered: Promptkit does not template or resolve
|
||||
files in them, and they can contain sensitive model output or application
|
||||
feedback. Promptkit remains stateless; every `Run` call re-resolves its current
|
||||
sources and the application owns any semantic retry budget. When a
|
||||
pre-execution equality check is required, use `PrepareExecution` and compare
|
||||
its opaque rendered-prompt hash before invoking `RunPrepared`.
|
||||
|
||||
## Inputs, Profiles, And Overrides
|
||||
|
||||
Use `File`, `Inline`, or `InlineWithURI` to construct request inputs. A request
|
||||
|
||||
@@ -82,7 +82,13 @@ allowed.
|
||||
|
||||
### Messages And Templates
|
||||
|
||||
Each message has a non-empty `role` and exactly one of:
|
||||
Each message has a `role` that Promptkit trims and lowercases. It must then be
|
||||
exactly one of `developer`, `system`, `user`, or `assistant`; blank, custom,
|
||||
`tool`, and `function` roles are invalid. This intentionally tightens the
|
||||
previous nonblank-string rule. Consumers migrating to the next minor release
|
||||
must update any nonstandard prompt-definition roles before upgrading.
|
||||
|
||||
Each message also has exactly one of:
|
||||
|
||||
- `content`, containing an inline Go template; or
|
||||
- `content_file`, naming a file whose contents are the Go template.
|
||||
|
||||
@@ -55,6 +55,12 @@ Each ordinary message contains its `role` and string `content`. A
|
||||
cache-controlled message instead uses a text content block containing `type`,
|
||||
`text`, and `cache_control`; an empty cache-control TTL is omitted.
|
||||
|
||||
Promptkit sends only `developer`, `system`, `user`, and `assistant` roles and
|
||||
does so without provider-specific translation. Tool and deprecated function
|
||||
payloads are outside this text-message contract. A backend or model that
|
||||
rejects an otherwise supported role or context returns its ordinary provider
|
||||
error, which follows the normal generation-error path.
|
||||
|
||||
The effective direct or prompt-rendered session ID is trimmed, limited to 256
|
||||
Unicode code points, and sent when nonempty as top-level `session_id`. It is
|
||||
never also sent as a session header.
|
||||
|
||||
@@ -21,8 +21,9 @@ uses internal domain values for rendered prompts, execution targets,
|
||||
structured output, responses, and token usage.
|
||||
|
||||
The runner supplies a fully resolved target after applying backend, profile,
|
||||
and request precedence. The client uses its endpoint, credential metadata,
|
||||
generation fields, and extra parameters. `BackendID` remains routing metadata
|
||||
and request precedence, plus canonical provider-bound text messages. The
|
||||
client uses its endpoint, credential metadata, generation fields, and extra
|
||||
parameters. `BackendID` remains routing metadata
|
||||
for the generation boundary and is not mapped into the provider payload.
|
||||
|
||||
Construction trims and validates a nonempty configured base URL and clones any
|
||||
|
||||
@@ -84,7 +84,8 @@ profile, or backend:
|
||||
schema metadata from it when required;
|
||||
2. load and hash input artifacts;
|
||||
3. render messages and the prompt-defined session;
|
||||
4. apply any direct session ID;
|
||||
4. apply any direct session ID, then append already-normalized request messages
|
||||
after the rendered definition messages;
|
||||
5. hash the effective rendered prompt; and
|
||||
6. construct the prepared value and preparation timing.
|
||||
|
||||
@@ -113,7 +114,10 @@ the prompt session template, and is applied after ordinary message rendering.
|
||||
A blank direct value retains prompt-template behavior. The runner clears the
|
||||
template only on a value copy of the definition, so the definition hash always
|
||||
describes the original source while the rendered-prompt hash includes the
|
||||
effective direct or rendered session.
|
||||
effective direct or rendered session and the complete effective message
|
||||
sequence. The rendered-prompt hash uses a versioned, length-framed SHA-256
|
||||
encoding of that session, every role and content value, and cache-control
|
||||
presence and values; its hexadecimal value is opaque.
|
||||
|
||||
The registry is read-only after engine construction. Concurrent `Prepare` and
|
||||
`Run` calls resolve independent defensive backend values and keep all
|
||||
@@ -146,9 +150,10 @@ each actual generation call.
|
||||
|
||||
After a failed `basic`, JSON, or JSON Schema validation with a positive frozen
|
||||
budget, the installed repairer can make a bounded corrective call. Each request
|
||||
starts with a fresh copy of the complete original rendered messages, includes
|
||||
only the latest nonempty candidate as an assistant message, and appends one
|
||||
corrective user message. Empty candidates omit that assistant message. The
|
||||
starts with a fresh copy of the complete effective message sequence (the
|
||||
configured prefix followed by the request suffix), includes only the latest
|
||||
nonempty candidate as an assistant message, and appends one corrective user
|
||||
message. Empty candidates omit that assistant message. The
|
||||
correction carries validation diagnostics as JSON data bounded to 64 KiB; the
|
||||
full diagnostics remain in the validation result.
|
||||
|
||||
|
||||
@@ -21,6 +21,12 @@ paths, content opening, and root containment. Each lookup remains a
|
||||
point-in-time scan: definitions and catalogs are not cached, and file-backed
|
||||
message content is opened only for the exact selected candidate.
|
||||
|
||||
Message roles are normalized through the shared domain owner by trimming
|
||||
Unicode whitespace and lowercasing. Only `developer`, `system`, `user`, and
|
||||
`assistant` are published; invalid roles remain selected prompt-definition
|
||||
failures rather than becoming request errors. Cache-control metadata uses the
|
||||
same shared domain normalization and defensive-copy rule.
|
||||
|
||||
Operating-system sources enforce containment against canonical roots and
|
||||
targets so symlinks cannot escape. Injected `fs.FS` sources enforce containment
|
||||
in their clean relative path namespace. A single-file source uses the selected
|
||||
@@ -122,8 +128,9 @@ Session and message parsing and execution remain synchronous. The renderer
|
||||
checks cancellation before and after each parse and execution boundary,
|
||||
between artifact conversion chunks, around each message, and before publishing
|
||||
the complete prompt. It cannot interrupt template work already in progress and
|
||||
never publishes a partial prompt after observing cancellation. It carries
|
||||
message roles, session IDs, and cache control into the rendered prompt. The
|
||||
never publishes a partial prompt after observing cancellation. It validates and
|
||||
canonicalizes message roles before carrying roles, session IDs, and cache
|
||||
control into the rendered prompt. The
|
||||
[renderer tests](../../internal/prompt/renderer_test.go) own rendering behavior.
|
||||
|
||||
## Schemas And Output Validation
|
||||
|
||||
@@ -347,6 +347,8 @@ structural repair, and opaque rendered-prompt identity.
|
||||
|
||||
## Stage 4: Publish Canonical Documentation And Complete Validation
|
||||
|
||||
**Status:** Complete
|
||||
|
||||
### Objective
|
||||
|
||||
Bring every canonical documentation owner into line with the implemented API,
|
||||
|
||||
@@ -571,6 +571,8 @@ func (e *Engine) InspectProfile(ctx context.Context, profileID string) (*Profile
|
||||
}
|
||||
|
||||
// Prepare resolves and renders a prompt request without calling an LLM.
|
||||
// It appends any validated RunRequest.AppendedMessages after rendered
|
||||
// definition messages in the returned caller-owned snapshot.
|
||||
//
|
||||
// Prepare selects the prompt and profile, resolves any selected backend and
|
||||
// effective execution settings, resolves the output contract, loads and hashes
|
||||
@@ -605,7 +607,8 @@ func (e *Engine) Prepare(ctx context.Context, req RunRequest) (*PreparedRun, err
|
||||
}
|
||||
|
||||
// PrepareExecution completely prepares a prompt request without calling the
|
||||
// configured LLMClient or reserving backend admission capacity.
|
||||
// configured LLMClient or reserving backend admission capacity. Validated
|
||||
// RunRequest.AppendedMessages are included in the frozen effective messages.
|
||||
//
|
||||
// The returned opaque handle is bound to this Engine and permits one
|
||||
// [Engine.RunPrepared] invocation. Preparation freezes the selected sources,
|
||||
@@ -637,7 +640,8 @@ func (e *Engine) PrepareExecution(ctx context.Context, req RunRequest) (*Prepare
|
||||
}
|
||||
|
||||
// Run prepares a request, invokes the configured LLMClient, and validates the
|
||||
// generated output.
|
||||
// generated output. Each call resolves current sources and composes a fresh,
|
||||
// stateless effective prompt with any validated RunRequest.AppendedMessages.
|
||||
//
|
||||
// A content-validation failure is a successful run whose
|
||||
// RunResult.Validation has Status ValidationFailed. When its output contract
|
||||
|
||||
@@ -3,12 +3,12 @@ package promptkit
|
||||
import "gitea.maximumdirect.net/eric/promptkit/internal/domain"
|
||||
|
||||
const (
|
||||
// RoleDeveloper identifies a developer instruction message.
|
||||
// RoleDeveloper identifies a provider-bound developer instruction message.
|
||||
RoleDeveloper = domain.RoleDeveloper
|
||||
// RoleSystem identifies a system instruction message.
|
||||
// RoleSystem identifies a provider-bound system instruction message.
|
||||
RoleSystem = domain.RoleSystem
|
||||
// RoleUser identifies a user message.
|
||||
// RoleUser identifies a provider-bound user message.
|
||||
RoleUser = domain.RoleUser
|
||||
// RoleAssistant identifies an assistant message.
|
||||
// RoleAssistant identifies a provider-bound assistant message.
|
||||
RoleAssistant = domain.RoleAssistant
|
||||
)
|
||||
|
||||
@@ -17,7 +17,9 @@ type PreparedExecution struct {
|
||||
|
||||
// Details returns a fresh caller-owned, credential-redacted copy of the
|
||||
// prepared request details. Mutating the result cannot affect execution or a
|
||||
// later Details call. Details remains available after execution or discard.
|
||||
// later Details call. Its complete effective message content, including any
|
||||
// appended request messages, remains subject to the caller's data-handling
|
||||
// policy. Details remains available after execution or discard.
|
||||
//
|
||||
// A nil receiver or zero-value PreparedExecution returns a zero [PreparedRun].
|
||||
func (p *PreparedExecution) Details() PreparedRun {
|
||||
|
||||
17
types.go
17
types.go
@@ -125,10 +125,11 @@ type RunRequest struct {
|
||||
Validation *OutputContract
|
||||
// AppendedMessages are already-rendered messages appended after every prompt
|
||||
// definition message. Promptkit neither templates nor resolves files in
|
||||
// them, and preserves valid content exactly. Nil and empty slices are
|
||||
// equivalent. Prepare, PrepareExecution, and Run validate and copy the
|
||||
// messages before source or model work; malformed values return an error
|
||||
// matching ErrInvalidRequest.
|
||||
// them, and preserves valid content exactly. Roles are trimmed and
|
||||
// lowercased, then must be [RoleDeveloper], [RoleSystem], [RoleUser], or
|
||||
// [RoleAssistant]. Nil and empty slices are equivalent. Prepare,
|
||||
// PrepareExecution, and Run validate and copy the messages before source or
|
||||
// model work; malformed values return an error matching ErrInvalidRequest.
|
||||
AppendedMessages []RenderedMessage
|
||||
}
|
||||
|
||||
@@ -632,13 +633,15 @@ type RenderedPrompt struct {
|
||||
// SessionID is the optional effective direct or rendered session
|
||||
// identifier supplied to the model client.
|
||||
SessionID string `json:"session_id,omitempty"`
|
||||
// Messages contains rendered messages in definition order.
|
||||
// Messages contains the frozen effective messages: definition messages in
|
||||
// their rendered order followed by any RunRequest.AppendedMessages.
|
||||
Messages []RenderedMessage `json:"messages"`
|
||||
}
|
||||
|
||||
// RenderedMessage is a prepared, provider-bound text chat message and has a
|
||||
// stable JSON representation. Its role must be one of [RoleDeveloper],
|
||||
// [RoleSystem], [RoleUser], or [RoleAssistant].
|
||||
// stable JSON representation. At a request boundary its role is trimmed and
|
||||
// lowercased, then must be one of [RoleDeveloper], [RoleSystem], [RoleUser],
|
||||
// or [RoleAssistant].
|
||||
type RenderedMessage struct {
|
||||
// Role is the provider-bound chat role.
|
||||
Role string `json:"role"`
|
||||
|
||||
Reference in New Issue
Block a user