Publish the Promptkit engine facade
This commit is contained in:
165
docs/consumers/pkg-promptkit.md
Normal file
165
docs/consumers/pkg-promptkit.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# Package `promptkit`
|
||||
|
||||
Import path:
|
||||
|
||||
```go
|
||||
import "gitea.maximumdirect.net/eric/promptkit"
|
||||
```
|
||||
|
||||
Package `promptkit` is the supported Go contract for in-process prompt
|
||||
preparation and execution. The declarations and their GoDoc in the
|
||||
[root package](../../doc.go) own the exact API; this guide explains how the
|
||||
pieces are used together.
|
||||
|
||||
## Engine Construction And Sources
|
||||
|
||||
Construct an engine with [`NewEngine`, `Config`, and
|
||||
`Option`](../../engine.go). `PromptDir` is required unless a prompt source
|
||||
option is supplied. `ProfileDir` optionally overlays built-in profiles, and an
|
||||
empty `SchemaDir` uses the current directory. `Timeout` is the transport-wide
|
||||
safety cap for the built-in OpenAI-compatible client. An optional `HTTPClient`
|
||||
is cloned; its positive timeout takes precedence.
|
||||
|
||||
Nil options are ignored. Invalid construction, including a nil injected client
|
||||
or artifact reader, returns an error matching `ErrInvalidConfig`.
|
||||
|
||||
The [source options](../../engine.go) replace their matching directory source:
|
||||
|
||||
- `WithPromptFS` and `WithPromptFile` select prompt definitions;
|
||||
- `WithProfileFS` and `WithProfileFile` overlay built-in profiles;
|
||||
- `WithProfiles` adds in-memory profiles ahead of file and built-in profiles;
|
||||
- `WithSchemaFS` and `WithSchemaFile` select JSON Schema documents;
|
||||
- `WithLLMClient` replaces the built-in model client; and
|
||||
- `WithArtifactReader` replaces the default reader for every input.
|
||||
|
||||
Prompt-content and schema paths from an `fs.FS` stay within the configured
|
||||
root. Single-file prompt and profile sources select definitions by YAML ID.
|
||||
Relative prompt content resolves from its prompt file, while a single schema
|
||||
is addressed by its base name.
|
||||
|
||||
Per-generation timeout values from profiles or requests are independent of
|
||||
the transport cap and caller context. An explicit request value of zero
|
||||
disables only the per-generation deadline. The
|
||||
[outbound integration contract](../integrations/openai-compatible-chat.md#timeout-and-cancellation)
|
||||
defines the complete timeout layering.
|
||||
|
||||
## Preparation And Execution
|
||||
|
||||
[`Engine.Prepare` and `Engine.Run`](../../engine.go) accept the public
|
||||
[`RunRequest`](../../types.go). `Prepare` resolves the prompt, profile, input
|
||||
artifacts, validation contract, and rendered messages without calling an LLM.
|
||||
`Run` performs the same preparation, calls the configured client, and validates
|
||||
the generated content.
|
||||
|
||||
```go
|
||||
engine, err := promptkit.NewEngine(promptkit.Config{
|
||||
PromptDir: "./prompts",
|
||||
ProfileDir: "./profiles",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
prepared, err := engine.Prepare(ctx, promptkit.RunRequest{
|
||||
PromptID: "meeting.summary",
|
||||
Inputs: map[string]promptkit.ArtifactRef{
|
||||
"transcript": promptkit.File("./transcript.md"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = prepared.Messages
|
||||
```
|
||||
|
||||
[`PreparedRun` and `RunResult`](../../types.go) expose copied public values.
|
||||
Preparation returns effective settings, hashes, rendered messages, selected
|
||||
profile, structured-output information, and timing without resolved secrets or
|
||||
model output. Execution adds the generated artifact and raw output, validation
|
||||
state, model metadata, usage, run ID, and duration.
|
||||
|
||||
A generated-content validation failure returns a result with
|
||||
`Validation.Status == ValidationFailed`. An inability to perform validation
|
||||
returns an error matching `ErrValidation`.
|
||||
|
||||
## Requests, Inputs, And Overrides
|
||||
|
||||
The [request and value declarations](../../types.go) own the available fields,
|
||||
serialized constants, and result shapes. Use `File`, `Inline`, or
|
||||
`InlineWithURI` to construct artifact references. Required declared inputs and
|
||||
every input referenced by a template must be supplied.
|
||||
|
||||
`ExecutionTargetOverride` uses pointers for numeric settings so an explicit
|
||||
zero remains distinct from no override. `ExtraParams` accepts JSON-compatible
|
||||
strings, booleans, finite numbers, string-keyed objects, arrays or slices, and
|
||||
nil. Unsupported values, non-string map keys, non-finite numbers, and cycles
|
||||
match `ErrInvalidConfig` in profiles or `ErrInvalidRequest` in request
|
||||
overrides.
|
||||
|
||||
Returned requests, profiles, prepared values, results, artifacts, maps, and
|
||||
slices are isolated from internal engine state. Consumers and injected
|
||||
extensions should not retain or mutate values owned by another caller.
|
||||
|
||||
## Profiles And Credentials
|
||||
|
||||
[`OpenAICompatibleProfile`](../../profiles.go) constructs an ordinary
|
||||
in-memory profile for an OpenAI-compatible chat-completions endpoint.
|
||||
`WithProfiles` rejects duplicate IDs in one call and gives in-memory profiles
|
||||
precedence over explicit file sources and built-ins.
|
||||
|
||||
Raw API keys do not belong in profiles. File-backed profiles may name an
|
||||
environment variable, while an in-memory profile can require a request key.
|
||||
A direct `RunRequest.APIKey` is request-scoped and takes precedence over an
|
||||
environment lookup for the built-in client.
|
||||
|
||||
API keys are excluded from JSON, prepared values, and results. The public
|
||||
`String` and `GoString` methods report only whether a direct key is present.
|
||||
Avoid reflection-based dumps of request structs, which can bypass that
|
||||
redaction.
|
||||
|
||||
## Extension Interfaces
|
||||
|
||||
The [`LLMClient`, `GenerateRequest`, and
|
||||
`GenerateResponse`](../../types.go) boundary lets a consumer replace model
|
||||
generation. Injected clients receive copied rendered messages, effective
|
||||
settings, explicit numeric-setting presence, structured-output constraints,
|
||||
and the request-scoped key. They return generated content and token usage.
|
||||
|
||||
The [`ArtifactReader`](../../types.go) boundary replaces the default inline and
|
||||
file reader for every input. Readers provide artifact content and metadata; the
|
||||
engine fills an empty artifact name from the input-map key. A reader error
|
||||
matches `ErrArtifactLoad` while preserving the original identity for
|
||||
`errors.Is`. A nil artifact with a nil error is also an artifact-load failure.
|
||||
|
||||
Extensions should honor context cancellation and avoid logging raw prompts,
|
||||
artifacts, or credentials.
|
||||
|
||||
## Errors
|
||||
|
||||
The [public error declarations](../../engine.go) and
|
||||
[mapping](../../errors.go) preserve these sentinel checks through `errors.Is`:
|
||||
|
||||
- `ErrInvalidConfig`
|
||||
- `ErrInvalidRequest`
|
||||
- `ErrPromptNotFound`
|
||||
- `ErrProfileNotFound`
|
||||
- `ErrProfileRequired`
|
||||
- `ErrPromptLoad`
|
||||
- `ErrProfileLoad`
|
||||
- `ErrAPIKeyEnvMissing`
|
||||
- `ErrArtifactLoad`
|
||||
- `ErrPromptRender`
|
||||
- `ErrLLMGenerate`
|
||||
- `ErrValidation`
|
||||
|
||||
`ErrProfileRequired` and `ErrAPIKeyEnvMissing` also match
|
||||
`ErrInvalidRequest`, allowing either broad request handling or a specific
|
||||
condition. Wrapped collaborator errors retain their identity where the public
|
||||
contract promises it.
|
||||
|
||||
## Consumer Boundary
|
||||
|
||||
Promptkit is an importable library. It does not own a command, inbound HTTP
|
||||
API, process configuration, or deployment policy. Scriptorium is one
|
||||
downstream application that maps this root package contract into those
|
||||
application concerns.
|
||||
@@ -5,8 +5,8 @@
|
||||
This document defines the outbound HTTP behavior implemented by Promptkit's
|
||||
internal OpenAI-compatible model client. The
|
||||
[internal model-client document](../internal/llm.md) owns implementation flow,
|
||||
errors, and test ownership. The client is not yet available through a usable
|
||||
public Promptkit engine.
|
||||
errors, and test ownership. The root Promptkit engine uses this client by
|
||||
default unless a consumer injects another implementation.
|
||||
|
||||
## Endpoint And Method
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ and the
|
||||
[OpenAI-compatible chat integration](../integrations/openai-compatible-chat.md)
|
||||
owns the observable outbound HTTP contract.
|
||||
|
||||
The client is implemented only under `internal/llm`. The root package does not
|
||||
yet assemble it into a usable public engine.
|
||||
The concrete client remains under `internal/llm`. The root engine assembles it
|
||||
as the default implementation behind Promptkit's public client boundary.
|
||||
|
||||
## Components And Flow
|
||||
|
||||
@@ -40,8 +40,8 @@ non-success provider statuses, and malformed successful responses. Provider
|
||||
response bodies are not included in non-success errors.
|
||||
|
||||
Caller cancellation and deadline failures during the outbound request are
|
||||
reported as request execution failures. The future runner can classify these
|
||||
identities without depending on HTTP status mapping.
|
||||
reported as request execution failures. The runner classifies these identities
|
||||
without depending on HTTP status mapping.
|
||||
|
||||
## Test Ownership
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ contributor workflow and validation.
|
||||
|
||||
| Component | Implemented responsibility | References |
|
||||
| --- | --- | --- |
|
||||
| Root `promptkit` package | Establishes the public package boundary for the Go module. It does not yet provide migrated framework behavior or exported APIs. | [Package declaration](../../doc.go) |
|
||||
| Root `promptkit` package | Provides the supported engine facade, source and injection options, public request and result values, built-in profile construction, extension interfaces, value conversion, redacted formatting, and public error mapping. | [Package GoDoc](../../doc.go), [engine assembly](../../engine.go) |
|
||||
| `internal/domain` | Defines internal framework values for requests, artifacts, prompt definitions, profiles, execution targets, rendering, generation, and validation. | [Domain declarations](../../internal/domain/domain.go) |
|
||||
| `internal/defaults` | Defines application-neutral framework constants and constructs the default execution target. It contains no CLI, server, or inbound HTTP limits. | [Framework defaults](../../internal/defaults/defaults.go) |
|
||||
| `internal/filecatalog` | Provides deterministic YAML discovery and path helpers for operating-system filesystems and `fs.FS` sources. | [File catalog](../../internal/filecatalog/catalog.go) |
|
||||
@@ -24,9 +24,8 @@ contributor workflow and validation.
|
||||
| `internal/llm` | Defines the internal generation boundary and implements outbound OpenAI-compatible chat requests, response decoding, authentication, and deadline handling. | [Internal model client](llm.md) |
|
||||
| `internal/usecase` | Coordinates preparation and execution across internal sources, rendering, artifact loading, generation, validation, and optional repair. | [Internal runner](runner.md) |
|
||||
|
||||
These packages provide the internal model, source, rendering, validation, and
|
||||
model-client workflow. A usable public engine is not implemented in Promptkit
|
||||
yet.
|
||||
The root package assembles these internal components without exposing their
|
||||
representations. Consumers depend only on the root facade.
|
||||
|
||||
## Maintenance
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ artifact, rendering, and validation behavior, while the
|
||||
[model-client document](llm.md) owns generation behavior and failure
|
||||
categories.
|
||||
|
||||
The runner remains under `internal/usecase`. The root package does not yet
|
||||
assemble it into a usable public engine.
|
||||
The runner remains under `internal/usecase` and is assembled by the root
|
||||
Promptkit engine. Its concrete type is not part of the public API.
|
||||
|
||||
## Collaborators
|
||||
|
||||
@@ -65,8 +65,8 @@ input hashes, token usage, a generated run identifier, and UTC timing.
|
||||
|
||||
Package errors distinguish invalid requests, required profile selection,
|
||||
credential failures, and prompt, profile, artifact, rendering, generation, and
|
||||
validation failures. Wrapping preserves the package identities needed by the
|
||||
future facade and retains collaborator identities where they are part of the
|
||||
validation failures. Wrapping preserves the package identities mapped by the
|
||||
public facade and retains collaborator identities where they are part of the
|
||||
internal contract. Context cancellation propagates through the invoked
|
||||
collaborator and is classified by the owning operation.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ This document describes Promptkit's implemented internal source, artifact,
|
||||
rendering, and output-validation behavior. The
|
||||
[architecture policy](../policy/architecture.md) owns the library boundary and
|
||||
dependency rules. None of these internal packages is a supported consumer API,
|
||||
and the root package does not yet assemble them into a usable engine.
|
||||
and the root engine assembles them behind its public source options and values.
|
||||
|
||||
## Prompt Definitions
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ Promptkit is an importable Go library. It does not provide a runnable command,
|
||||
an HTTP service, or another application process.
|
||||
|
||||
The module root contains package `promptkit`, which is the public facade. It
|
||||
declares the module's public package boundary but does not yet provide a usable
|
||||
exported framework API.
|
||||
provides the supported engine, configuration and source options, requests,
|
||||
results, public values, extension interfaces, profiles, and error sentinels.
|
||||
|
||||
The implemented internal components consist of:
|
||||
|
||||
@@ -40,17 +40,19 @@ The implemented internal components consist of:
|
||||
- `internal/usecase`, which coordinates preparation and execution across the
|
||||
internal framework components.
|
||||
|
||||
The defaults and renderer depend on the domain model. Prompt-definition and
|
||||
profile repositories use the domain model, file catalog, and YAML decoder. The
|
||||
built-in profile repository supplies an embedded `fs.FS` to the profile
|
||||
package. Artifact reading uses the domain model and application-neutral
|
||||
defaults. Validation uses the domain model, file catalog, and JSON Schema
|
||||
implementation. The model client uses the domain model, application-neutral
|
||||
defaults, and an injected or standard-library HTTP client. The use-case runner
|
||||
depends on the narrow interfaces owned by each internal component. The public
|
||||
engine has not yet been extracted.
|
||||
The root facade assembles the internal repositories, renderer, validator,
|
||||
outbound client, and use-case runner while translating public values and
|
||||
errors at the library boundary. The defaults and renderer depend on the domain
|
||||
model. Prompt-definition and profile repositories use the domain model, file
|
||||
catalog, and YAML decoder. The built-in profile repository supplies an
|
||||
embedded `fs.FS` to the profile package. Artifact reading uses the domain model
|
||||
and application-neutral defaults. Validation uses the domain model, file
|
||||
catalog, and JSON Schema implementation. The model client uses the domain
|
||||
model, application-neutral defaults, and an injected or standard-library HTTP
|
||||
client. The use-case runner depends on the narrow interfaces owned by each
|
||||
internal component.
|
||||
|
||||
Future framework extraction must follow this dependency direction:
|
||||
The current implementation follows this dependency direction:
|
||||
|
||||
```text
|
||||
downstream consumers, including Scriptorium
|
||||
@@ -65,16 +67,13 @@ downstream consumers, including Scriptorium
|
||||
narrow injected abstractions
|
||||
```
|
||||
|
||||
The facade may coordinate internal components once the public engine is
|
||||
extracted. Internal components must depend on narrow abstractions for behavior
|
||||
supplied from outside the library; they must not depend on consumers or on
|
||||
Scriptorium. This diagram is the target dependency direction for later
|
||||
extraction and does not assert that the public facade already assembles the
|
||||
implemented foundation.
|
||||
The facade coordinates internal components and adapts the supported public
|
||||
extension interfaces to narrow internal abstractions. Internal components must
|
||||
not depend on consumers or on Scriptorium.
|
||||
|
||||
## Repository And Consumer Boundary
|
||||
|
||||
Scriptorium is a downstream application that will consume Promptkit through
|
||||
Scriptorium is a downstream application that consumes Promptkit through
|
||||
the supported public facade. It is not a Promptkit package and must not become
|
||||
an internal dependency.
|
||||
|
||||
@@ -147,7 +146,6 @@ state.
|
||||
|
||||
## Current-State Maintenance
|
||||
|
||||
This policy distinguishes present implementation from constraints on future
|
||||
framework extraction. Do not list planned packages as implemented components.
|
||||
When extraction introduces a package, update the internal inventory and the
|
||||
owning contract or subsystem document in the same change.
|
||||
Do not list planned packages as implemented components. When implementation
|
||||
introduces a package, update the internal inventory and the owning contract or
|
||||
subsystem document in the same change.
|
||||
|
||||
Reference in New Issue
Block a user