72 lines
3.5 KiB
Markdown
72 lines
3.5 KiB
Markdown
# Structured Generation Errors
|
|
|
|
## Purpose
|
|
|
|
Promptkit should give downstream applications actionable, machine-readable
|
|
details when the built-in OpenAI-compatible client receives a non-success HTTP
|
|
response. Today the client reports only the status code and discards the
|
|
provider response body. This makes ordinary configuration failures—such as an
|
|
unsupported strict JSON Schema keyword—unnecessarily difficult to diagnose.
|
|
|
|
## Target End State
|
|
|
|
Failures from the built-in transport are available through a public typed error
|
|
that works with `errors.As` while continuing to match `ErrLLMGenerate` through
|
|
`errors.Is`. The error should expose:
|
|
|
|
- the HTTP status code;
|
|
- a normalized provider error code or type when supplied; and
|
|
- a bounded provider message extracted from a recognized OpenAI-compatible
|
|
JSON error envelope.
|
|
|
|
The ordinary `Error()` string should remain safe and concise: it should include
|
|
the status and provider code or type, but not automatically include the
|
|
provider message. Consumers that deliberately want the provider's diagnostic
|
|
text can retrieve it from the typed error and apply their own disclosure and
|
|
logging policy.
|
|
|
|
This contract should be available for both ordinary and prepared execution.
|
|
Errors returned by injected model clients must continue to preserve their own
|
|
identity and should not be converted into fabricated HTTP details.
|
|
|
|
## Safety And Compatibility Boundaries
|
|
|
|
- Never expose the raw response body, response headers, endpoint, credentials,
|
|
request messages, schema document, or generated content through this API.
|
|
- Read only a small fixed maximum response body, reject malformed or
|
|
unrecognized envelopes, normalize invalid UTF-8 and control characters, and
|
|
cap every retained diagnostic field independently.
|
|
- Treat the extracted provider message as untrusted and potentially sensitive:
|
|
its GoDoc must tell consumers not to log or display it without applying their
|
|
own policy.
|
|
- Preserve the existing generic behavior when a response is empty, non-JSON,
|
|
oversized, or does not match a recognized error envelope.
|
|
- Do not assign retryability from an HTTP status. Promptkit supplies facts;
|
|
downstream applications retain retry and presentation policy.
|
|
|
|
## Recommended API Direction
|
|
|
|
Prefer one immutable public `GenerationError` value, constructed internally and
|
|
carrying accessors for HTTP status, provider code or type, and provider message.
|
|
This keeps the exact representation evolvable while giving consumers an
|
|
idiomatic `errors.As` contract. Public Go declarations and GoDoc should own the
|
|
final exact names and semantics.
|
|
|
|
The internal OpenAI-compatible client should parse only the conventional
|
|
top-level `error` envelope and pass normalized details through the use-case and
|
|
public error-mapping layers. The integration documentation should continue to
|
|
own wire behavior; the public declarations should own the consumer contract.
|
|
|
|
## Acceptance Criteria
|
|
|
|
- A downstream consumer can distinguish a provider HTTP 400 from other
|
|
generation failures and obtain a bounded provider explanation when present.
|
|
- The typed error still satisfies `errors.Is(err, ErrLLMGenerate)`.
|
|
- Existing cancellation, capacity, validation, and injected-client error
|
|
identities remain unchanged.
|
|
- Tests cover recognized string and numeric provider codes, absent and malformed
|
|
envelopes, oversized bodies and fields, control characters, and error-chain
|
|
behavior without making live provider requests.
|
|
- Current-state GoDoc and the OpenAI-compatible integration and internal-client
|
|
documents are updated only when the implementation lands.
|