Repository navigation
Releases: cognesy/instructor-logging
Release list
v2.14.1
title: 'v2.14.1'
v2.14.1 is a maintenance release for Polyglot. BatchInference remains an
opt-in early access feature.
See the BatchInference guide
and provider capability table
for usage and provider support details.
v2.14.0
title: 'v2.14.0'
v2.14.0 adds native asynchronous batch inference to Polyglot. BatchInference is
an early access feature for applications that want to submit provider batch
jobs and process their results separately from request submission.
Polyglot BatchInference (Early Access)
The new opt-in BatchInference facade supports provider-native job submission,
status retrieval, cancellation where available, result streaming, and remote
job listing. Applications can persist a job reference and resume work in a
later process. Results retain caller keys and expose per-item outcomes as they
become available.
Provider APIs differ in their supported operations, input modes, and model
eligibility. See the BatchInference guide
and provider capability table before
choosing a provider. The examples include deterministic offline runs and
explicit commands for live jobs.
Upgrade Notes
Existing inference, embeddings, and decision APIs require no changes.
BatchInference is opt-in. The optional Amazon Bedrock transport requires
aws/aws-sdk-php; other Polyglot providers do not require it.
v2.13.0
title: 'v2.13.0'
v2.13.0 expands Polyglot Decision with three new hosted providers and updates
the documentation index and model inventory.
Decision providers
- Polyglot Decision adds a Fastino GLiDE driver (
fastinopreset, model
fastino/GLiDE). It answers Noul, Choice, and Score questions with up to 255
Choice options or Score levels and a 40,000-token limit per state plus one
question. Cold-model425responses are retried after the documented 60
second wait. - Cloudflare Clef and Perplexity Decision drivers are now bundled.
- Polyglot Embeddings adds a Perplexity driver.
- The model catalog documentation lists every bundled Decision model with its
limits and pricing, including Fastino at $0.15 per million input tokens.
Documentation
llms.txtis now spec-compliant, with absolute links.- The Decision provider evaluation example can run the
fastinopreset.
Upgrade Notes
- Set
FASTINO_API_KEYonly for applications that use the Fastino preset. - Fastino recommends a read timeout of at least 300 seconds; see the Fastino
guide for warming-aware HTTP client and retry settings.
v2.12.0
title: 'v2.12.0'
v2.12.0 adds vector retrieval and structured decisions to InstructorPHP,
expands exact-model metadata, and brings new Echo and RESPAN integrations. It
also includes an embedding configuration cutover; review the upgrade notes
before updating.
Retrieval and agent knowledge access
- The new
cognesy/instructor-retrievalpackage provides document processing,
vector storage, semantic search, bounded context assembly, and citations.
Bundled stores include in-memory, pgvector, Qdrant, Typesense, Meilisearch,
Weaviate, and Milvus. - Retrieval composes with Polyglot Embeddings and leaves answer generation to
the application, so callers control how evidence enters inference requests. - Agents can opt into bounded search and evidence-reading tools. Query, result,
context, and read sizes are policy-controlled. Evidence reads pass through
an application-owned authorization boundary.
Structured decisions and model metadata
- Polyglot adds a typed Decision runtime for Noul, Choice, and Score questions.
Adapters cover Classifier.dev, Jeff, Laya, TypeSafe, and RESPAN. - Noul answers can carry positive, negative, and unknown probabilities. RESPAN
supports Noul questions and reports access failures separately from request
validation errors. - Exact Embedding and Decision model catalogs expose reviewed capabilities and
limits, with pricing where available. Examples show model metadata and cost
estimates.
Provider and integration updates
- The Echo inference driver supports Fulcrum's persona-based writing API and
requires a non-emptypersonaoption on each request or preset. - Embedding request model overrides now select the effective model for catalog
lookup and provider request construction. Missing provider token counts
remain unknown instead of being converted to zero. - The cURL transport negotiates HTTP/2 over TLS by default and handles interim
response headers before the final response.
Upgrade Notes
- Embedding configuration no longer accepts
dimensions,defaultDimensions,
ormaxInputsinEmbeddingsConfig, DSNs, presets, or Laravel and Symfony
embedding connection configuration. Set a requested dimension in request
options, for examplewithOptions(['dimensions' => 256]). Inject an
Embedding model catalog intoEmbeddingsRuntimewhen catalog-based
input-limit checks are required. - Embedding usage counts and totals can now be
nullwhen a provider omits
them, and embedding cost calculation can returnnull. Handle unknown usage
explicitly. UseEmbeddingsUsage::zero()for a known zero total;none()
represents unknown usage. - Add
ECHO_API_KEYorRESPAN_API_KEYonly for applications that use the
corresponding provider.
v2.11.0
title: 'v2.11.0'
description: Typed structured decisions and TypeSafe connectivity in Polyglot.
v2.11.0 introduces structured decision models as a third Polyglot operation
family alongside inference and embeddings. Applications can now evaluate text
or structured state through strictly typed Noul, Choice, and Score
questions without depending on a provider-specific SDK.
TypeSafe is the first Decision provider. The bundled typesafe preset uses the
TYPESAFE_API_KEY environment variable and the jev-latest model alias.
Typed structured decisions
The new Cognesy\Polyglot\Decision namespace provides:
Decision,DecisionProvider,DecisionRuntime, andPendingDecision- provider-neutral
DecisionRequestandDecisionResponseobjects - typed
Noul,Choice, andScorequestions - typed answers with validated probability distributions
- application-owned Choice option IDs and ordered Score levels
- text, object, or list state through
JsonContent - portable
toArray()andfromArray()payloads
use Cognesy\Polyglot\Decision\Collections\ChoiceOptions;
use Cognesy\Polyglot\Decision\Collections\Questions;
use Cognesy\Polyglot\Decision\Data\ChoiceOption;
use Cognesy\Polyglot\Decision\Decision;
use Cognesy\Polyglot\Decision\Questions\Choice;
$questions = Questions::of(
new Choice(
id: 'route',
options: ChoiceOptions::of(
new ChoiceOption('billing'),
new ChoiceOption('technical'),
new ChoiceOption('other'),
),
instructions: 'Choose the best support route.',
),
);
$route = Decision::using('typesafe')
->with(
input: 'I was charged twice. Please reverse the duplicate charge.',
questions: $questions,
)
->get()
->choice('route')
->value();Decision input does not need to be JSON. Passing a PHP string sends text state;
JsonContent::object() and JsonContent::list() preserve structured state when
named fields or list position matter.
Runtime, retries, and observability
Decision follows Polyglot's established facade, request, pending handle,
runtime, driver, and response shape. create() is lazy, and one
PendingDecision memoizes both successful responses and terminal failures.
There is no Decision stream: one execution returns one validated typed result.
Retries are opt-in through DecisionRetryPolicy. The Decision execution session
is the single retry owner, applies bounded backoff and jitter, and honors bounded
Retry-After for retriable provider responses.
The runtime emits execution and attempt lifecycle events and projects them as
sdm.decision and sdm.decision.attempt telemetry spans. Default event and
telemetry payloads omit state, question content, provider bodies, credentials,
and exception messages.
TypeSafe adapter and extension points
The TypeSafe driver translates the stable Decision domain to the System One API
and validates that returned IDs, primitive kinds, Choice winners, Score legends,
and probability distributions match the original request.
Provider failures are normalized into Decision-specific authentication, invalid
request, rate-limit, transient, and response exceptions. Custom providers can
implement CanProcessDecisionRequest and register through
DecisionDriverRegistry without changing application-facing request or answer
types.
Configuration and documentation
Decision presets live under config/sdm. The release also makes bundled
default.yaml discovery consistent for LLM, embeddings, and SDM configuration
in aggregate and standalone Composer installations.
Polyglot documentation now covers question design, typed response handling,
configuration, runtime composition, retries, lifecycle events, telemetry,
errors, testing, and custom drivers. Four executable B06_Decisions examples
demonstrate primitives, dynamic choices, structured state, and explicit runtime
composition.
v2.10.1
title: v2.10.1
description: Standalone package QA fixes for the v2.10 release train.
Fixed
- Resolve the Polyglot concurrency test autoloader from the standalone package when split-package tests run outside the monorepo.
- Keep Tell package tests independent of Polyglot test-only fixtures.
- Clear Tell package PHPStan and Psalm findings after resolving the v2.10 dependency train.
v2.10.0
title: 'v2.10.0'
v2.10.0 makes the assistant turn a first-class Message across Polyglot,
Instructor, and Agents. This is an intentional breaking change. There is no
deprecated compatibility layer for the previous flattened response or streaming
delta shapes.
The release also removes Polyglot's lazy aliases for classes moved under
Cognesy\Polyglot\Support in v2.7. Applications must use the canonical
Support\Redaction\SensitiveDataRedactor, Support\Retry\RetryBackoff,
Support\Retry\RetryJitter, Support\Retry\RetryPolicyInvariants, and
Support\Pricing\Cost FQCNs.
Exact-offering model catalog
Polyglot now provides an optional deterministic model catalog keyed by exact
(driver, wire model). Ordinary inference does not discover or load it. Applications compose a
catalog explicitly when they need local capability enforcement, model metadata, or facts required
by a selected processor. Unknown custom offerings remain executable and carry explicit unknown
facts when inspected.
Offering facts are stored as individual versioned YAML files using the connection-preset loading
pattern. Runtime construction reads no model records; exact lookup loads only the selected
offering and reuses its immutable profile. Project records use
config/llm/models/<encoded-driver>/<encoded-model>.yaml; monolithic runtime models.json
discovery was removed. Strict record parsing rejects unknown keys and malformed facts.
This replaces and removes CanDescribeCapabilities, DriverCapabilities, and
SpecifiedInferenceDriver. Default providers now use BaseInferenceRequestDriver directly.
Reasoning capability facts also live in the exact offering record; provider drivers retain only
the constant wire format used to render an already-approved selection.
Request preflight is an in-process preparation step, not an LLM API request. It reads only facts
explicitly attached to the request, rejects features and combinations marked unsupported, and
preserves unknown facts for custom offerings. Missing model facts do not create a catalog veto.
Reasoning translation can instead receive the narrow required facts directly. Model-name regexes
are no longer a capability source.
Provider adapters now render the approved intent or throw a precise protocol error; they never
silently strip a response format or weaken tool choice. Known semantic fallback is disabled by
default and requires LLMConfig::$allowLossyFallback === true (allow_lossy_fallback in Laravel
and Symfony connection configuration). Every accepted fallback is recorded on the effective
request and emitted with InferenceRequested.
Catalog maintenance is explicit and offline: edit the reviewed source inputs, run
just models-build, and use just models-check plus just models-validate as deterministic QA.
There is no runtime refresh, staging, apply, mapping, or provenance subsystem.
LLMConfig and connection presets no longer own contextLength, maxOutputLength, or
pricing. Put limits, modalities, and capabilities in a model catalog record. Supply pricing
explicitly to the existing inference or embeddings cost calculator. LLMConfig::fromArray()
ignores fields outside its canonical constructor shape; Agents has no legacy migration layer.
Anthropic prompt caching
Inference::withCachedContext() and StructuredOutput::withCachedContext() now
accept an optional ttl: '5m' or ttl: '1h'. Omitting it keeps Anthropic's
five-minute default. Explicit block TTLs are preserved, including when cached
contexts are serialized and restored.
Cached tool-use and tool-result messages now place the breakpoint on the actual
eligible content block, without inserting an empty text block. Signed thinking
history remains intact and is not used as a breakpoint target.
Automatic caching remains opt-in through
->withOptions(['cache_control' => ['type' => 'ephemeral']]); add 'ttl' => '1h'
inside that object for a one-hour automatic cache. This is distinct from the
explicit-prefix withCachedContext() API. The caching guide now explains both
modes, their shared limits, and model-specific minimum prefix lengths.
Ordered Assistant Messages
InferenceResponse now carries one assistant Message. Its ordered
ContentParts can contain text, reasoning, tool calls, and tool results without
splitting a turn into unrelated response fields. Text, reasoning, and tool-call
accessors are projections on Message:
$response = $inference->response();
$message = $response->message();
$message->parts(); // ordered ContentParts
$message->content()->toString(); // visible text projection
$message->reasoningContent(); // reasoning projection
$message->toolCalls(); // tool-call projectionInference::get() and PendingInference::get() now return that Message, not
a string. Call ->content()->toString() explicitly when an application needs
only text.
Provider adapters and streaming use the same assistant-message assembler. Stable
block identities preserve interleaved content, reasoning, and parallel tool calls.
Anthropic thinking signatures, Gemini thought signatures, and OpenAI Responses
reasoning replay state remain attached to their blocks so a completed assistant
turn can be sent back on the next request.
Structured output streams now retain token usage reported in a provider's terminal
usage-only event. After finalValue() or finalResponse(), $stream->usage() and
the final response expose the provider-reported input, output, cache, and reasoning
counts.
The openai-compatible, ollama, and together drivers now preserve reasoning
returned in reasoning_content, reasoning, thinking, or analysis fields for
both synchronous and streamed responses. For synchronous responses without one of
those fields, an inline <think>...</think> block is moved from visible content
into the message's reasoning part.
Agents now archive the exact response message. They no longer reconstruct an
assistant message from text, infer tool calls from separate fields, or JSON-parse
text to guess whether a provider leaked tool arguments.
Migration
Tell runtime and composition
Tell now has one direct execution path: Tell creates a fresh concrete
TellRuntime through the final Core\Execution\TellRuntimeFactory. The shallow
runner and runtime-factory interface chain was removed. CLI, conversations, and
the one-run protocol use the same factory; request-scoped cancellation still
overrides the host cancellation source.
Direct tool dispatch now resolves TellRequest configuration through
CanResolveTellConfiguration. It no longer receives the complete runtime merely
to obtain effective configuration, and it still does not execute an agent turn.
StandaloneTellBuilder exposes only named, typed replacement points. Migrate
custom integrations as follows:
| Before 2.10.0 | 2.10.0 |
|---|---|
CanRunTell |
Use the public Tell facade; use TellRuntimeFactory only when composing delivery adapters |
CanCreateTellRuntime |
Core\Execution\TellRuntimeFactory |
CanExecuteTellRuntime |
concrete Core\Execution\TellRuntime |
DefaultTellRunner |
removed; Tell creates a runtime through TellRuntimeFactory |
Composition\Standalone\Profile\StandardTellRuntimeFactory |
Core\Execution\TellRuntimeFactory |
withInstance(CanObserveTellExecution::class, $observer) |
withObserver($observer) |
withInstance(CanResolveTellModel::class, $resolver) |
withModelResolver($resolver) |
withSingleton($contract, $factory) |
construct the supported replacement explicitly, then call its named builder method |
There are no aliases, deprecated interfaces, dual registrations, or generic
container-binding fallback in 2.10.
The four default driver tables now have one entry point on their registry. The old static wrapper
classes and reasoning capability accessors were removed without aliases:
| Removed | Replacement |
|---|---|
BundledInferenceDrivers::registry() |
InferenceDriverRegistry::default() |
BundledInferenceDrivers::specifications() |
private registry implementation |
BundledInferenceDrivers::reasoningCapabilities() |
explicit ModelCatalog lookup or request-scoped ReasoningCapabilities |
BundledEmbeddingsDrivers::registry() |
EmbeddingsDriverRegistry::default() |
BundledHttpDrivers::registry() |
HttpDriverRegistry::default() |
BundledHttpPools::registry() |
HttpPoolRegistry::default() |
BundledReasoning |
exact records in models-overrides.json |
InferenceDriverSpec::$reasoning |
InferenceDriverSpec::$reasoningWireFormat |
CanTranslateReasoning::capabilities() |
explicitly supplied request or exact model facts |
ModelModalities::$inputVideo, $outputImage, $outputAudio |
removed until adapters implement them |
ModelModalities::$inputFile was also removed because Polyglot has no maintained generic file
message-to-wire route. ModelCapabilities::$reasoning remains an optional typed model fact, and
the narrower reasoning facts can be attached directly to a request. Custom driver registrations
should start from InferenceDriverRegistry::default() when they want the shipped table, or
InferenceDriverRegistry::make() when they want an empty one.
Replace flattened response access with the canonical message:
| Before 2.10.0 | 2.10.0 |
|---|---|
$inference->get() returns string |
$inference->get() returns Message |
$response->content() |
$response->message()->content()->toString() |
$response->reasoningContent() |
$response->message()->reasoningContent() |
$response->toolCalls() |
$response->message()->toolCalls() |
$response->hasContent() |
!$response->message()->content()->isEmpty() |
$response->hasReasoningContent() |
$response->message()->reasoningContent() !== '' |
$response->hasToolCalls() |
$response->message()->hasToolCalls() |
$response->withContent($text) |
`$response->withMessage... |
v2.9.5
title: 'v2.9.5'
v2.9.5 makes Tell's subprocess integration tests portable to standalone
package installations.
Standalone Tell Verification
- Arena concurrency workers receive the active package-aware Composer
autoloader explicitly instead of inferring a monorepo layout. - The ordinary-host isolation test uses the same package-aware test autoloader.
- Released-package verification now exercises these subprocess contracts on
PHP 8.3, 8.4, and 8.5.
No runtime API changes or application migration steps are required.
v2.9.4
title: 'v2.9.4'
v2.9.4 completes deterministic teardown for the local HTTP servers used by
standalone package verification.
Laravel Package Verification
- The Laravel integration suite launches PHP's built-in server as a directly
owned process instead of through a shell child. - Test ports are allocated dynamically and the exact process is terminated at
suite teardown. - Server readiness checks avoid leaking connection warnings into Pest.
Standalone Instructor Verification
- The
instructor-structtest contract no longer invokes the monorepo-only
documentation tool from a released package checkout. - Package documentation remains covered by the root documentation QA lane
before release.
No runtime API changes or application migration steps are required.
v2.9.3
title: 'v2.9.3'
v2.9.3 corrects the HTTP Client integration-test server used by split-package
verification. v2.9.2 published the standalone package contracts successfully,
but its released-artifact matrix exposed a monorepo-relative autoloader path in
the HTTP Client test server.
HTTP Client Package Verification
- The integration server resolves Composer's autoloader in both standalone
packages and the monorepo. - Test servers use a package-owned process instead of a shell child, allowing
deterministic teardown after the suite. - Test ports are allocated dynamically and failure diagnostics retain the
actual attempted port.
No runtime API changes or application migration steps are required. Consumers
adopting the v2.9 Tell and reasoning changes should use v2.9.3.