2026-07-17 03:06:23 +00:00
|
|
|
|
# LLM Runtime Internals
|
|
|
|
|
|
|
2026-07-26 13:33:45 +00:00
|
|
|
|
`internal/framework/llm` is Notarius’s provider-independent structured
|
2026-07-28 16:31:36 +00:00
|
|
|
|
completion boundary. It adapts framework requests to PromptKit, bounds
|
2026-07-26 13:33:45 +00:00
|
|
|
|
provider calls, assembles registered prompt and schema assets, records selected
|
|
|
|
|
|
profiles, and redacts provider errors. The architectural boundary is defined in
|
|
|
|
|
|
[Architecture](../policy/architecture.md#llm-boundary); profile sources,
|
|
|
|
|
|
credentials, and concurrency settings belong in
|
2026-07-28 16:52:49 +00:00
|
|
|
|
[Configuration](../config.md#promptkit-profiles) and
|
2026-07-26 13:33:45 +00:00
|
|
|
|
[Configuration](../config.md#concurrency-output-cache-and-debug).
|
|
|
|
|
|
|
|
|
|
|
|
## Structured Completion Boundary
|
|
|
|
|
|
|
|
|
|
|
|
Modules and LLM-backed validators depend only on
|
|
|
|
|
|
`contracts.StructuredLLMClient`. A completion request supplies a prompt ID and
|
|
|
|
|
|
version, optional profile and session IDs, named input material, variables, and
|
|
|
|
|
|
a caller-owned decode target. The successful response returns the validated raw
|
|
|
|
|
|
structured bytes together with non-secret provider, model, profile, and token
|
|
|
|
|
|
metadata.
|
|
|
|
|
|
|
|
|
|
|
|
The caller owns the domain behavior: it chooses the prompt, prepares inputs,
|
|
|
|
|
|
selects the private response schema, and interprets the decoded result. The
|
|
|
|
|
|
adapter does not own source evidence, artifact conversion, normalization, or
|
|
|
|
|
|
durable schemas. Those responsibilities remain with the module and its
|
|
|
|
|
|
[integration contract](../integrations/).
|
|
|
|
|
|
|
2026-07-28 16:31:36 +00:00
|
|
|
|
`PromptKitClient` validates the request target and prompt identity, maps each
|
|
|
|
|
|
named material to a PromptKit inline artifact while preserving its origin URI,
|
2026-07-28 16:52:49 +00:00
|
|
|
|
maps the request session to the existing `session_id` prompt variable, forwards
|
|
|
|
|
|
profile selection, then prepares and runs the prompt. PromptKit v0.1.0 has no
|
|
|
|
|
|
direct request-level session field. The adapter returns PromptKit’s validated
|
|
|
|
|
|
raw bytes rather than re-encoding the decoded target. An empty optional
|
|
|
|
|
|
material is represented as one space so its named input is retained by
|
|
|
|
|
|
PromptKit.
|
2026-07-26 13:33:45 +00:00
|
|
|
|
|
|
|
|
|
|
An empty request profile lets the prompt select its configured default. The CLI
|
|
|
|
|
|
prepares every explicitly selected binding profile before a run begins, so a
|
|
|
|
|
|
missing explicit profile fails before stage execution. Calls record the profile
|
2026-07-28 16:31:36 +00:00
|
|
|
|
actually selected by PromptKit; the recorder deduplicates non-secret profile
|
2026-07-28 16:52:49 +00:00
|
|
|
|
identity, provider, and model values for manifest use. Successful completion
|
|
|
|
|
|
responses and recorded profile manifests identify the adapter provider as
|
|
|
|
|
|
`promptkit`.
|
2026-07-26 13:33:45 +00:00
|
|
|
|
|
2026-07-28 13:36:01 -05:00
|
|
|
|
Before execution, the adapter also contributes a non-secret checkpoint
|
|
|
|
|
|
fingerprint for the effective PromptKit profile source. It combines the
|
|
|
|
|
|
identity of PromptKit's compiled-in profile catalog with a deterministic digest
|
|
|
|
|
|
of every YAML profile in the configured profile directory, or of the configured
|
|
|
|
|
|
profile file. The fingerprint contains neither profile content nor source
|
|
|
|
|
|
paths. It covers both explicit binding profiles and prompt-selected defaults,
|
|
|
|
|
|
so changing a model or other profile setting cannot reuse checkpoints created
|
|
|
|
|
|
under the prior profile source. This cache identity is independent of durable
|
|
|
|
|
|
profile provenance: run manifests continue to list only profiles actually
|
|
|
|
|
|
observed during LLM calls.
|
|
|
|
|
|
|
2026-07-26 13:33:45 +00:00
|
|
|
|
## Shared Provider-Call Limit
|
|
|
|
|
|
|
2026-07-28 16:31:36 +00:00
|
|
|
|
Production construction creates one PromptKit client and wraps it in one
|
2026-07-26 13:33:45 +00:00
|
|
|
|
scheduled client. The scheduler has a fixed, positive permit limit, serves
|
|
|
|
|
|
queued calls in FIFO order, and removes a queued call when its context is
|
|
|
|
|
|
cancelled. A granted permit is released exactly once on every completion path.
|
|
|
|
|
|
|
|
|
|
|
|
The scheduled wrapper surrounds every `CompleteStructured` call, so concurrent
|
|
|
|
|
|
lanes, pipeline retries, and LLM-backed validators share the same provider-call
|
|
|
|
|
|
ceiling. This ceiling is independent of pipeline worker concurrency; changing
|
|
|
|
|
|
worker counts cannot exceed the configured LLM limit. The configuration field
|
|
|
|
|
|
and its effective default are owned by
|
|
|
|
|
|
[Configuration](../config.md#concurrency-output-cache-and-debug).
|
2026-07-17 08:49:08 +00:00
|
|
|
|
|
2026-07-17 03:06:23 +00:00
|
|
|
|
## Prompt And Schema Assets
|
|
|
|
|
|
|
2026-07-26 13:33:45 +00:00
|
|
|
|
An `AssetRegistry` collects prompt and schema filesystems from production module
|
2026-07-28 16:31:36 +00:00
|
|
|
|
families. It flattens registered roots into the PromptKit filesystems and
|
2026-07-26 13:33:45 +00:00
|
|
|
|
rejects invalid roots, unreadable assets, duplicate paths, and missing prompt
|
|
|
|
|
|
or schema files during preparation. The framework’s `promptfs` helper combines
|
|
|
|
|
|
module-owned prompt files with reusable domain fragments without making the
|
|
|
|
|
|
framework depend on D&D content.
|
|
|
|
|
|
|
|
|
|
|
|
Each LLM-backed module owns its prompt declaration, package-specific assets,
|
|
|
|
|
|
and private response schema. Shared D&D wording is owned by the D&D shared
|
|
|
|
|
|
asset package; the detailed D&D conventions are in
|
|
|
|
|
|
[D&D Module Internals](dnd.md). The mounted prompt assets used by a module also
|
|
|
|
|
|
determine its prompt fingerprint. Schema loaders validate JSON, attach identity
|
|
|
|
|
|
and digest metadata, make defensive copies, and expose diagnostics without raw
|
|
|
|
|
|
schema bytes.
|
|
|
|
|
|
|
|
|
|
|
|
Private response schemas validate a model transport envelope. They are not the
|
|
|
|
|
|
durable artifact schema and should not be documented as an external wire
|
|
|
|
|
|
contract. Durable formats and compatibility rules remain in the
|
|
|
|
|
|
[integration contracts](../integrations/).
|
|
|
|
|
|
|
|
|
|
|
|
## Prompt Maintenance And Backend Caching
|
|
|
|
|
|
|
|
|
|
|
|
Prompt message order and shared asset bytes are runtime behavior. Backend cache
|
2026-07-27 20:16:11 +00:00
|
|
|
|
reuse depends on identical preceding roles, rendered bytes, and cache-control
|
|
|
|
|
|
metadata—not merely equivalent meaning. Keep reusable shared assets
|
|
|
|
|
|
byte-identical and preserve each prompt’s declared ordering and cache controls
|
|
|
|
|
|
when editing it.
|
|
|
|
|
|
|
|
|
|
|
|
For sibling prompts that can reuse the same source material, order universal
|
|
|
|
|
|
shared context first, request source material next, and module-specific
|
|
|
|
|
|
suffixes last. Put a cache boundary at a reusable prefix that is useful to the
|
|
|
|
|
|
backend. Redundant intermediate cache boundaries do not extend that reusable
|
|
|
|
|
|
prefix and add no value.
|
|
|
|
|
|
|
|
|
|
|
|
Prompt-family owners may choose a different sequence when their inputs and
|
|
|
|
|
|
reuse pattern differ. The D&D family’s extraction, scene-chunking, and NPC
|
|
|
|
|
|
normalization policies are maintained in [D&D Module Internals](dnd.md#prompt-construction).
|
|
|
|
|
|
Do not add tests that enforce prompt prose; prompt tests should verify the
|
|
|
|
|
|
meaningful input placement and cache controls of the prompt being changed.
|
2026-07-26 13:33:45 +00:00
|
|
|
|
|
|
|
|
|
|
## Validation, Repair, And Retries
|
|
|
|
|
|
|
2026-07-28 16:31:36 +00:00
|
|
|
|
PromptKit performs prompt rendering, provider execution, and the prompt’s
|
2026-07-26 13:33:45 +00:00
|
|
|
|
structured-output validation. The adapter reports an empty result, validation
|
|
|
|
|
|
failure, empty structured body, or decode failure as
|
|
|
|
|
|
`ErrInvalidStructuredOutput`, while retaining the returned raw bytes and debug
|
|
|
|
|
|
material when they exist. Provider failures remain operational errors rather
|
|
|
|
|
|
than output-validation failures.
|
|
|
|
|
|
|
2026-07-28 16:31:36 +00:00
|
|
|
|
Prompt-declared repair is executed within PromptKit’s structured-output flow.
|
2026-07-26 13:33:45 +00:00
|
|
|
|
The current production D&D prompt manifests set repair attempts to zero. That
|
|
|
|
|
|
setting does not replace pipeline retry behavior: a binding’s configured retry
|
|
|
|
|
|
count reruns its stage attempt after an error or rejection, and an exhausted
|
|
|
|
|
|
rejection is a recorded output rather than a provider error. The pipeline owns
|
|
|
|
|
|
attempt lifecycle, validation chains, and retry diagnostics; see
|
|
|
|
|
|
[Pipeline Internals](pipeline.md#validation-retries-and-output) and the
|
|
|
|
|
|
[binding reference](../config.md#module-bindings-and-validators).
|
|
|
|
|
|
|
2026-07-28 16:52:49 +00:00
|
|
|
|
## Timeout Ownership
|
|
|
|
|
|
|
|
|
|
|
|
The caller context remains the outer cancellation authority. PromptKit applies
|
|
|
|
|
|
a positive effective generation timeout as an inner request deadline; an
|
|
|
|
|
|
explicit zero disables only that generation deadline. The HTTP client timeout
|
|
|
|
|
|
is a separate transport-wide cap. Notarius forwards the caller context and
|
|
|
|
|
|
does not install another timeout wrapper around PromptKit.
|
|
|
|
|
|
|
|
|
|
|
|
The selected PromptKit profile owns generation settings. Notarius binding
|
|
|
|
|
|
retries remain outside the adapter and repeat the complete module operation
|
|
|
|
|
|
and validation chain. PromptKit v0.1.0 does not add a provider retry loop.
|
|
|
|
|
|
Operator-facing behavior is summarized in
|
|
|
|
|
|
[Operations](../operations.md#operational-limits), and the pinned upstream
|
|
|
|
|
|
contract is identified in
|
|
|
|
|
|
[PromptKit Integration](../integrations/pkg-promptkit.md).
|
|
|
|
|
|
|
2026-07-26 13:33:45 +00:00
|
|
|
|
## Observability And Redaction
|
|
|
|
|
|
|
|
|
|
|
|
When debug recording is enabled, the pipeline decorates the shared client. The
|
|
|
|
|
|
wrapper records prepared prompt and response material, timing, selected profile
|
|
|
|
|
|
and model, and call identifiers in the run’s debug bundle, including material
|
|
|
|
|
|
available from a failed structured completion. For a successful completion, a
|
|
|
|
|
|
debug-write failure is surfaced; when the completion already failed, its call
|
|
|
|
|
|
error remains the result. Debug-bundle location, retention, and handling are
|
|
|
|
|
|
operational concerns documented in [Operations](../operations.md#debug-bundles).
|
|
|
|
|
|
|
|
|
|
|
|
Run manifests receive selected profile summaries and component identities, not
|
|
|
|
|
|
prompt, schema, source, reference, or response content. Provider error text is
|
|
|
|
|
|
wrapped with prompt context and bearer credentials are redacted before it
|
|
|
|
|
|
crosses the runtime boundary. Known-secret redaction is available to other
|
|
|
|
|
|
runtime collaborators; it does not make prompt or response contents safe for
|
|
|
|
|
|
general logging.
|
|
|
|
|
|
|
|
|
|
|
|
## Failure Boundaries
|
|
|
|
|
|
|
|
|
|
|
|
- Construction fails for missing asset registries, mutually exclusive profile
|
|
|
|
|
|
sources, invalid asset registration, or a non-positive scheduler limit.
|
|
|
|
|
|
- Preparation failures, unavailable explicit profiles, provider failures, and
|
|
|
|
|
|
context cancellation propagate to the calling stage with context.
|
|
|
|
|
|
- Malformed or schema-invalid provider output is classified separately as
|
|
|
|
|
|
invalid structured output so the module or pipeline can apply its own retry
|
|
|
|
|
|
and rejection policy.
|
|
|
|
|
|
- Domain semantic checks, evidence decisions, and deterministic normalization
|
|
|
|
|
|
run outside the provider adapter.
|
|
|
|
|
|
|
|
|
|
|
|
## Focused Verification
|
|
|
|
|
|
|
|
|
|
|
|
Read the LLM adapter, scheduler, asset registry, schema loader, and redaction
|
|
|
|
|
|
tests when changing this boundary. Prompt changes also require the owning
|
|
|
|
|
|
module’s asset tests, and retry or debug changes require focused pipeline or
|
|
|
|
|
|
CLI coverage. The focused runtime and D&D checks are:
|
|
|
|
|
|
|
|
|
|
|
|
~~~sh
|
|
|
|
|
|
go test ./internal/framework/llm/... ./internal/modules/dnd/...
|
|
|
|
|
|
~~~
|