feat(Docker): Upgrade to PHP 8.5.0RC3 with native ext-uri support
BREAKING CHANGE: Requires PHP 8.5.0RC3 Changes: - Update Docker base image from php:8.4-fpm to php:8.5.0RC3-fpm - Enable ext-uri for native WHATWG URL parsing support - Update composer.json PHP requirement from ^8.4 to ^8.5 - Add ext-uri as required extension in composer.json - Move URL classes from Url.php85/ to Url/ directory (now compatible) - Remove temporary PHP 8.4 compatibility workarounds Benefits: - Native URL parsing with Uri\WhatWg\Url class - Better performance for URL operations - Future-proof with latest PHP features - Eliminates PHP version compatibility issues
This commit is contained in:
@@ -149,7 +149,7 @@ final readonly class CachePerformanceStorage implements PerformanceStorage
|
||||
unset($predictionKeys[$i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Convert timestamp back to DateTimeImmutable
|
||||
if (is_int($prediction['timestamp'])) {
|
||||
$prediction['timestamp'] = (new \DateTimeImmutable())->setTimestamp($prediction['timestamp']);
|
||||
@@ -174,6 +174,104 @@ final readonly class CachePerformanceStorage implements PerformanceStorage
|
||||
return $deletedCount;
|
||||
}
|
||||
|
||||
public function getRecentPredictions(
|
||||
string $modelName,
|
||||
Version $version,
|
||||
int $limit
|
||||
): array {
|
||||
$indexKey = $this->getPredictionsIndexKey($modelName, $version);
|
||||
$result = $this->cache->get($indexKey);
|
||||
$predictionKeys = $result->value ?? [];
|
||||
|
||||
if (empty($predictionKeys)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$predictions = [];
|
||||
|
||||
// Get predictions in reverse order (most recent first)
|
||||
foreach (array_reverse($predictionKeys) as $keyString) {
|
||||
if (count($predictions) >= $limit) {
|
||||
break;
|
||||
}
|
||||
|
||||
$predictionKey = CacheKey::fromString($keyString);
|
||||
$result = $this->cache->get($predictionKey);
|
||||
|
||||
$prediction = $result->value;
|
||||
|
||||
if ($prediction === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Convert timestamp back to DateTimeImmutable
|
||||
if (is_int($prediction['timestamp'])) {
|
||||
$prediction['timestamp'] = (new \DateTimeImmutable())->setTimestamp($prediction['timestamp']);
|
||||
}
|
||||
|
||||
$predictions[] = $prediction;
|
||||
}
|
||||
|
||||
return $predictions;
|
||||
}
|
||||
|
||||
public function calculateAccuracy(
|
||||
string $modelName,
|
||||
Version $version,
|
||||
int $limit
|
||||
): float {
|
||||
$predictions = $this->getRecentPredictions($modelName, $version, $limit);
|
||||
|
||||
if (empty($predictions)) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
$correctCount = 0;
|
||||
$totalCount = 0;
|
||||
|
||||
foreach ($predictions as $prediction) {
|
||||
// Only count predictions that have actual labels for accuracy calculation
|
||||
if (!isset($prediction['actual_label'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$totalCount++;
|
||||
|
||||
if (isset($prediction['predicted_label'])
|
||||
&& $prediction['predicted_label'] === $prediction['actual_label']) {
|
||||
$correctCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($totalCount === 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return $correctCount / $totalCount;
|
||||
}
|
||||
|
||||
public function getConfidenceBaseline(
|
||||
string $modelName,
|
||||
Version $version
|
||||
): ?array {
|
||||
$baselineKey = CacheKey::fromString(
|
||||
self::CACHE_PREFIX . ":{$modelName}:{$version->toString()}:baseline"
|
||||
);
|
||||
|
||||
$result = $this->cache->get($baselineKey);
|
||||
$baseline = $result->value;
|
||||
|
||||
if ($baseline === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'avg_confidence' => $baseline['avg_confidence'],
|
||||
'std_dev_confidence' => $baseline['std_dev_confidence'],
|
||||
'stored_at' => $baseline['stored_at'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add prediction key to index
|
||||
*/
|
||||
|
||||
@@ -97,6 +97,86 @@ final class InMemoryPerformanceStorage implements PerformanceStorage
|
||||
return $initialCount - count($this->predictions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get recent predictions with limit
|
||||
*/
|
||||
public function getRecentPredictions(
|
||||
string $modelName,
|
||||
Version $version,
|
||||
int $limit
|
||||
): array {
|
||||
// Filter by model and version
|
||||
$filtered = array_filter(
|
||||
$this->predictions,
|
||||
fn($record) =>
|
||||
$record['model_name'] === $modelName
|
||||
&& $record['version'] === $version->toString()
|
||||
);
|
||||
|
||||
// Sort by timestamp descending (most recent first)
|
||||
usort($filtered, fn($a, $b) => $b['timestamp'] <=> $a['timestamp']);
|
||||
|
||||
// Limit results
|
||||
return array_values(array_slice($filtered, 0, $limit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate accuracy from recent predictions
|
||||
*/
|
||||
public function calculateAccuracy(
|
||||
string $modelName,
|
||||
Version $version,
|
||||
int $limit
|
||||
): float {
|
||||
$predictions = $this->getRecentPredictions($modelName, $version, $limit);
|
||||
|
||||
if (empty($predictions)) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
$correctCount = 0;
|
||||
$totalCount = 0;
|
||||
|
||||
foreach ($predictions as $prediction) {
|
||||
// Only count predictions that have actual labels
|
||||
if (!isset($prediction['actual_label'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$totalCount++;
|
||||
|
||||
if (isset($prediction['predicted_label'])
|
||||
&& $prediction['predicted_label'] === $prediction['actual_label']) {
|
||||
$correctCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($totalCount === 0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return $correctCount / $totalCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get confidence baseline as array
|
||||
*/
|
||||
public function getConfidenceBaseline(
|
||||
string $modelName,
|
||||
Version $version
|
||||
): ?array {
|
||||
$key = $this->getBaselineKey($modelName, $version);
|
||||
|
||||
if (!isset($this->confidenceBaselines[$key])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'avg_confidence' => $this->confidenceBaselines[$key]['avg'],
|
||||
'std_dev_confidence' => $this->confidenceBaselines[$key]['stdDev'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get baseline key for confidence storage
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user