ADR-077: Plain completion joins the named-configuration path
- Status
-
Accepted
- Date
-
2026-07-17
- Authors
-
Netresearch DTT GmbH
Context
The three-tier model (Provider → Model → Configuration,
ADR-001) reaches every chat-shaped and embedding
capability through a *For entry point:
chat, stream,
chat and — since
ADR-055 — embed all resolve the
adapter from a DB-backed Llm and run through the
middleware pipeline, so budgets are enforced and cost is attributed per
configuration.
The high-level Completion did not. Its complete family
resolves only the instance-default configuration (chat picks the
active default, ADR-034). A consumer that needs several
distinct named text configurations — a summariser, a classifier and a
chatbot in one extension — could not target them by identifier; every
plain completion went to the single default. The low-level
Llm existed but routes
through the provider's raw complete operation (no system-prompt
shaping, no response-format normalisation, no per-user budget metadata),
so it is not a drop-in for the message-based complete path.
Decision
Plain completion joins the configuration path.
`Llm` mirrors
chat's default-configuration branch — it builds the system/user
Chat value objects, injects the configuration's skills, and
threads the per-user budget and idempotency metadata from the options —
but against the caller's chosen configuration instead of the resolved
default. A pinned provider on the options is irrelevant on the
configuration path and is dropped, exactly as chat does. The method
takes a typed Chat rather than the low-level
complete metadata/override arrays, so budget and
idempotency parity is handled once inside the manager.
The high-level feature service follows.
Completion gains the named-configuration counterparts
of its whole family: complete,
complete, complete,
complete and
complete. Each applies the same option
transforms as its instance-default twin (response-format normalisation,
Markdown system-prompt augmentation, factual/creative presets) before
delegating to the manager — the shared transforms are extracted into
private helpers so the two paths cannot drift.
Method-based, not a Chat field. Targeting a configuration is
expressed as an explicit Llm parameter, consistent with
the entire *For family, keeping Chat a pure
scalar readonly DTO.
Consequences
- Completion consumers select a backend-managed configuration by identifier instead of relying on the single instance default; per-configuration budgets and cost attribution apply to plain completion like to every other capability.
- Behaviour parity holds: the JSON/Markdown/factual/creative variants apply identical transforms on the configuration path as on the instance-default path, guaranteed by shared private helpers rather than duplicated logic.
CompletionandService Interface Llmgained methods — implementers outside this repo must add them. In-repo the concrete services and the hand-writtenService Manager Interface Statictest double are updated.Completion Service - The low-level
complete(rawWith Configuration () completeoperation) is unchanged and remains available for callers that deliberately want the non-chat completion endpoint.