Skip to content

v0.17.0

Choose a tag to compare

@github-actions github-actions released this 13 Jul 09:42
v0.17.0
71f34c3

The consumer-integration release

The heart of 0.17.0 is one review: nr_ai_search — an extension building a full retrieval stack on nr_llm — documented where the integration surface forced workarounds. The six API changes in this release (ADR-051 through ADR-056) each remove one of them.

Narrower contracts: tool calling and exceptions

Consumers that need tool calling no longer need to bind to the full LlmServiceManagerInterface — 19 methods when this was decided, 20 by the end of this very release, which is exactly the problem: every hand-written test double of the manager broke whenever the interface grew. The new ToolCallingServiceInterface exposes chatWithTools() and chatWithToolsForConfiguration(), so a test double is two methods (ADR-051, #348).

Error handling narrows the same way: every exception nr_llm throws on its public surface now implements NrLlmExceptionInterface, so one catch arm replaces the six-class enumeration. That includes the ChatMessage/ToolSpec/ToolCall::fromArray() normalization errors, which previously threw PHP's own InvalidArgumentException and forced a separate catch (ADR-053, #350).

Tool conversations are typed end to end

The two turns every tool loop needs — the assistant turn carrying the model's tool calls, and the tool turn answering one of them — are ChatMessage value objects now, built with ChatMessage::assistantToolCalls() and ChatMessage::toolResult(). No more hand-built wire arrays, no more re-encoding arguments yourself: the wire shape (including the empty-arguments {}-vs-[] pitfall) is handled once, inside the value object, and round-trips through fromArray(). The tool-calling guide is rewritten on top of the typed API (ADR-054, #352, closes #345).

Embeddings join the configuration family

embedForConfiguration() resolves vault key, model, and pricing from a database-backed configuration, giving embedding consumers per-configuration budgets and cost attribution — the treatment chat-shaped calls always had. Model records can now declare their embedding dimensions, letting an extension that persists vectors validate its index against the configured model instead of probing with a live call (ADR-055, #353, closes #346).

Usage attribution now honors the beUserUid the option objects already carried: frontend plugins and CLI workers get correct usage rows without impersonating a technical backend user around every call, and the budget gate and the usage row can no longer disagree about whose call it was (ADR-052, #349).

Extensions can ship their configuration needs

A consuming extension can declare the configurations it needs as presets: requirements — capabilities and selection criteria — never providers, models, or API keys. nr_llm lists declared presets that have no record yet, preflights them against the configured models (naming the missing requirement instead of importing something dead), and an admin confirms the import. The imported record runs in criteria mode and resolves against what the instance has (ADR-056, #354, closes #347). v1 exposes this through admin-gated AJAX endpoints; a backend module UI is a planned follow-up (ADR-056).

Ollama reasoning models

Hybrid-thinking models get a reasoning toggle (#341), and Ollama's native message.thinking is surfaced on completion responses (#342) — CompletionResponse::$thinking / hasThinking().

PHP JIT disabled for functional tests

A silent engine segfault — reproduced on the PHP 8.3 and 8.5 container images, triggered by valid source shapes — was traced to the tracing JIT; the functional test suites now run with the JIT disabled (#351).

Notes for implementers

Three interfaces gained members in this release: LlmServiceManagerInterface::embedForConfiguration(), EmbeddingServiceInterface::embedForConfiguration()/embedBatchForConfiguration(), and a trailing ?int $beUserUid = null parameter on UsageTrackerServiceInterface::trackUsage(). Hand-written fakes and implementations outside this repository must add them; runtime callers are unaffected.

Pull requests

#341, #342, #343, #344, #348, #349, #350, #351, #352, #353, #354, #355 — ADR-050 through ADR-056, in Documentation/Adr/.

Full changelog: v0.16.1...v0.17.0