Release Notes - v1.16.0¶
New Features¶
OutputFormat API¶
Control output format independently from schema:
// Get raw arrays instead of objects
$data = StructuredOutput::with(...)
->intoArray()
->get();
// Deserialize to different class than schema
$user = StructuredOutput::with(...)
->intoInstanceOf(User::class)
->get();
// Self-deserializing objects
$obj = StructuredOutput::with(...)
->intoObject($customObject)
->get();
Pluggable Extraction¶
Custom JSON extraction strategies:
use Cognesy\Instructor\Extraction\Contracts\CanExtractResponse;
use Cognesy\Instructor\Extraction\Data\ExtractionInput;
use Cognesy\Instructor\Extraction\Exceptions\ExtractionException;
class CustomExtractor implements CanExtractResponse {
public function extract(ExtractionInput $input): array {
// custom extraction logic
// throw ExtractionException on failure
}
public function name(): string {
return 'custom';
}
}
StructuredOutput::with(...)
->withExtractors(
new CustomExtractor(),
new ResilientJsonExtractor(),
)
->get();
Built-in extractors:
- DirectJsonExtractor - Parse as-is
- ResilientJsonExtractor - Handle malformed JSON
- MarkdownBlockExtractor - Extract from code blocks
- BracketMatchingExtractor - Find first { to last }
- SmartBraceExtractor - Handle escaped quotes
Extraction Events¶
Track extraction lifecycle:
- ExtractionStarted
- ExtractionStrategyAttempted
- ExtractionStrategySucceeded
- ExtractionStrategyFailed
- ExtractionCompleted
- ExtractionFailed
Manual Schema Support¶
JSON schemas no longer require x-php-class:
$schema = [
'type' => 'object',
'properties' => [
'name' => ['type' => 'string'],
],
];
// Returns raw array when no class specified
$data = StructuredOutput::with(
messages: 'John',
responseModel: $schema
)->get();
Response Caching¶
use Cognesy\Polyglot\Inference\Enums\ResponseCachePolicy;
// Cache responses in memory
$response = Inference::with(...)
->withCachePolicy(ResponseCachePolicy::Memory)
->get();
Improvements¶
- Simplified processing pipeline
- Removed unused partial validations
Bug Fixes¶
- Fixed
withInput()to handle objects correctly - Fixed
HostSandboxto run inbaseDir(fixes CLI agents) - Fixed environment inheritance for agent execution
- Fixed exit code propagation in examples
- Resolved all PHPStan errors
New Package: metrics¶
Event-driven metrics collection system.
Metric types: - Counter - incremental counts - Gauge - point-in-time values - Histogram - value distributions - Timer - duration measurements
Usage:
use Cognesy\Metrics\Collectors\MetricsCollector;
use Cognesy\Metrics\Metrics;
// Create custom collector
class StreamMetricsCollector extends MetricsCollector {
protected function listeners(): array {
return [
StreamFirstChunkReceived::class => $this->onFirstChunk(...),
InferenceCompleted::class => $this->onCompleted(...),
];
}
public function onFirstChunk(StreamFirstChunkReceived $event): void {
$this->timer('llm.stream.ttfc_ms', $event->timeToFirstChunkMs, [
'model' => $event->model,
]);
}
public function onCompleted(InferenceCompleted $event): void {
$this->gauge('llm.output_tokens', (float) $event->usage->output());
}
}
// Register collector and exporter
$metrics = new Metrics($events);
$metrics
->collect(new StreamMetricsCollector())
->exportTo(new CallbackExporter(fn($metrics) => dump($metrics)));
// Metrics auto-collected from events
$metrics->export();