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
|
[`OutputContract` GoDoc](../../types.go) for the exact budget and eligibility
|
||||||
rules.
|
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
|
## Inputs, Profiles, And Overrides
|
||||||
|
|
||||||
Use `File`, `Inline`, or `InlineWithURI` to construct request inputs. A request
|
Use `File`, `Inline`, or `InlineWithURI` to construct request inputs. A request
|
||||||
|
|||||||
@@ -82,7 +82,13 @@ allowed.
|
|||||||
|
|
||||||
### Messages And Templates
|
### 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`, containing an inline Go template; or
|
||||||
- `content_file`, naming a file whose contents are the Go template.
|
- `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`,
|
cache-controlled message instead uses a text content block containing `type`,
|
||||||
`text`, and `cache_control`; an empty cache-control TTL is omitted.
|
`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
|
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
|
Unicode code points, and sent when nonempty as top-level `session_id`. It is
|
||||||
never also sent as a session header.
|
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.
|
structured output, responses, and token usage.
|
||||||
|
|
||||||
The runner supplies a fully resolved target after applying backend, profile,
|
The runner supplies a fully resolved target after applying backend, profile,
|
||||||
and request precedence. The client uses its endpoint, credential metadata,
|
and request precedence, plus canonical provider-bound text messages. The
|
||||||
generation fields, and extra parameters. `BackendID` remains routing metadata
|
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.
|
for the generation boundary and is not mapped into the provider payload.
|
||||||
|
|
||||||
Construction trims and validates a nonempty configured base URL and clones any
|
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;
|
schema metadata from it when required;
|
||||||
2. load and hash input artifacts;
|
2. load and hash input artifacts;
|
||||||
3. render messages and the prompt-defined session;
|
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
|
5. hash the effective rendered prompt; and
|
||||||
6. construct the prepared value and preparation timing.
|
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
|
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
|
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
|
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
|
The registry is read-only after engine construction. Concurrent `Prepare` and
|
||||||
`Run` calls resolve independent defensive backend values and keep all
|
`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
|
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
|
budget, the installed repairer can make a bounded corrective call. Each request
|
||||||
starts with a fresh copy of the complete original rendered messages, includes
|
starts with a fresh copy of the complete effective message sequence (the
|
||||||
only the latest nonempty candidate as an assistant message, and appends one
|
configured prefix followed by the request suffix), includes only the latest
|
||||||
corrective user message. Empty candidates omit that assistant message. The
|
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
|
correction carries validation diagnostics as JSON data bounded to 64 KiB; the
|
||||||
full diagnostics remain in the validation result.
|
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
|
point-in-time scan: definitions and catalogs are not cached, and file-backed
|
||||||
message content is opened only for the exact selected candidate.
|
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
|
Operating-system sources enforce containment against canonical roots and
|
||||||
targets so symlinks cannot escape. Injected `fs.FS` sources enforce containment
|
targets so symlinks cannot escape. Injected `fs.FS` sources enforce containment
|
||||||
in their clean relative path namespace. A single-file source uses the selected
|
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,
|
checks cancellation before and after each parse and execution boundary,
|
||||||
between artifact conversion chunks, around each message, and before publishing
|
between artifact conversion chunks, around each message, and before publishing
|
||||||
the complete prompt. It cannot interrupt template work already in progress and
|
the complete prompt. It cannot interrupt template work already in progress and
|
||||||
never publishes a partial prompt after observing cancellation. It carries
|
never publishes a partial prompt after observing cancellation. It validates and
|
||||||
message roles, session IDs, and cache control into the rendered prompt. The
|
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.
|
[renderer tests](../../internal/prompt/renderer_test.go) own rendering behavior.
|
||||||
|
|
||||||
## Schemas And Output Validation
|
## Schemas And Output Validation
|
||||||
|
|||||||
@@ -347,6 +347,8 @@ structural repair, and opaque rendered-prompt identity.
|
|||||||
|
|
||||||
## Stage 4: Publish Canonical Documentation And Complete Validation
|
## Stage 4: Publish Canonical Documentation And Complete Validation
|
||||||
|
|
||||||
|
**Status:** Complete
|
||||||
|
|
||||||
### Objective
|
### Objective
|
||||||
|
|
||||||
Bring every canonical documentation owner into line with the implemented API,
|
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.
|
// 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
|
// Prepare selects the prompt and profile, resolves any selected backend and
|
||||||
// effective execution settings, resolves the output contract, loads and hashes
|
// 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
|
// 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
|
// The returned opaque handle is bound to this Engine and permits one
|
||||||
// [Engine.RunPrepared] invocation. Preparation freezes the selected sources,
|
// [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
|
// 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
|
// A content-validation failure is a successful run whose
|
||||||
// RunResult.Validation has Status ValidationFailed. When its output contract
|
// RunResult.Validation has Status ValidationFailed. When its output contract
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ package promptkit
|
|||||||
import "gitea.maximumdirect.net/eric/promptkit/internal/domain"
|
import "gitea.maximumdirect.net/eric/promptkit/internal/domain"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// RoleDeveloper identifies a developer instruction message.
|
// RoleDeveloper identifies a provider-bound developer instruction message.
|
||||||
RoleDeveloper = domain.RoleDeveloper
|
RoleDeveloper = domain.RoleDeveloper
|
||||||
// RoleSystem identifies a system instruction message.
|
// RoleSystem identifies a provider-bound system instruction message.
|
||||||
RoleSystem = domain.RoleSystem
|
RoleSystem = domain.RoleSystem
|
||||||
// RoleUser identifies a user message.
|
// RoleUser identifies a provider-bound user message.
|
||||||
RoleUser = domain.RoleUser
|
RoleUser = domain.RoleUser
|
||||||
// RoleAssistant identifies an assistant message.
|
// RoleAssistant identifies a provider-bound assistant message.
|
||||||
RoleAssistant = domain.RoleAssistant
|
RoleAssistant = domain.RoleAssistant
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ type PreparedExecution struct {
|
|||||||
|
|
||||||
// Details returns a fresh caller-owned, credential-redacted copy of the
|
// Details returns a fresh caller-owned, credential-redacted copy of the
|
||||||
// prepared request details. Mutating the result cannot affect execution or a
|
// 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].
|
// A nil receiver or zero-value PreparedExecution returns a zero [PreparedRun].
|
||||||
func (p *PreparedExecution) Details() PreparedRun {
|
func (p *PreparedExecution) Details() PreparedRun {
|
||||||
|
|||||||
17
types.go
17
types.go
@@ -125,10 +125,11 @@ type RunRequest struct {
|
|||||||
Validation *OutputContract
|
Validation *OutputContract
|
||||||
// AppendedMessages are already-rendered messages appended after every prompt
|
// AppendedMessages are already-rendered messages appended after every prompt
|
||||||
// definition message. Promptkit neither templates nor resolves files in
|
// definition message. Promptkit neither templates nor resolves files in
|
||||||
// them, and preserves valid content exactly. Nil and empty slices are
|
// them, and preserves valid content exactly. Roles are trimmed and
|
||||||
// equivalent. Prepare, PrepareExecution, and Run validate and copy the
|
// lowercased, then must be [RoleDeveloper], [RoleSystem], [RoleUser], or
|
||||||
// messages before source or model work; malformed values return an error
|
// [RoleAssistant]. Nil and empty slices are equivalent. Prepare,
|
||||||
// matching ErrInvalidRequest.
|
// PrepareExecution, and Run validate and copy the messages before source or
|
||||||
|
// model work; malformed values return an error matching ErrInvalidRequest.
|
||||||
AppendedMessages []RenderedMessage
|
AppendedMessages []RenderedMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -632,13 +633,15 @@ type RenderedPrompt struct {
|
|||||||
// SessionID is the optional effective direct or rendered session
|
// SessionID is the optional effective direct or rendered session
|
||||||
// identifier supplied to the model client.
|
// identifier supplied to the model client.
|
||||||
SessionID string `json:"session_id,omitempty"`
|
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"`
|
Messages []RenderedMessage `json:"messages"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenderedMessage is a prepared, provider-bound text chat message and has a
|
// RenderedMessage is a prepared, provider-bound text chat message and has a
|
||||||
// stable JSON representation. Its role must be one of [RoleDeveloper],
|
// stable JSON representation. At a request boundary its role is trimmed and
|
||||||
// [RoleSystem], [RoleUser], or [RoleAssistant].
|
// lowercased, then must be one of [RoleDeveloper], [RoleSystem], [RoleUser],
|
||||||
|
// or [RoleAssistant].
|
||||||
type RenderedMessage struct {
|
type RenderedMessage struct {
|
||||||
// Role is the provider-bound chat role.
|
// Role is the provider-bound chat role.
|
||||||
Role string `json:"role"`
|
Role string `json:"role"`
|
||||||
|
|||||||
Reference in New Issue
Block a user