Compare commits
5 Commits
claude/cos
...
fix/opik-u
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82ed5227af | ||
|
|
c4e8deb3ef | ||
|
|
c6ee23fcd4 | ||
|
|
60efe08200 | ||
|
|
b9c3e4e7d1 |
@@ -5,6 +5,15 @@ All notable changes to PRAutoBlogger will be documented in this file.
|
|||||||
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project uses [Semantic Versioning](https://semver.org/).
|
and this project uses [Semantic Versioning](https://semver.org/).
|
||||||
|
|
||||||
|
## [0.12.1] — 2026-04-23
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- **Opik UUID v7 bug** — `PRAutoBlogger_Opik_Trace_Context` was generating trace and
|
||||||
|
span IDs with `wp_generate_uuid4()` (UUID v4). Opik's REST API requires UUID v7 and
|
||||||
|
rejects v4 with HTTP 400 "Trace id must be a version 7 UUID". Added a private static
|
||||||
|
`generate_uuid7()` method using `microtime()` + `random_bytes()` and replaced both
|
||||||
|
call sites. All trace and span submissions now succeed.
|
||||||
|
|
||||||
## [0.12.0] — 2026-04-23
|
## [0.12.0] — 2026-04-23
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class PRAutoBlogger_Opik_Trace_Context {
|
|||||||
* @return string The trace ID (UUID).
|
* @return string The trace ID (UUID).
|
||||||
*/
|
*/
|
||||||
public function init_trace(): string {
|
public function init_trace(): string {
|
||||||
$this->trace_id = wp_generate_uuid4();
|
$this->trace_id = self::generate_uuid7();
|
||||||
$this->trace_start = microtime( true );
|
$this->trace_start = microtime( true );
|
||||||
return $this->trace_id;
|
return $this->trace_id;
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ class PRAutoBlogger_Opik_Trace_Context {
|
|||||||
* @return string Generated span ID (UUID).
|
* @return string Generated span ID (UUID).
|
||||||
*/
|
*/
|
||||||
public function start_span( array $span_data ): string {
|
public function start_span( array $span_data ): string {
|
||||||
$span_id = wp_generate_uuid4();
|
$span_id = self::generate_uuid7();
|
||||||
|
|
||||||
$span = array(
|
$span = array(
|
||||||
'id' => $span_id,
|
'id' => $span_id,
|
||||||
@@ -193,4 +193,44 @@ class PRAutoBlogger_Opik_Trace_Context {
|
|||||||
public static function teardown(): void {
|
public static function teardown(): void {
|
||||||
self::$instance = null;
|
self::$instance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a UUID version 7 (time-ordered, random).
|
||||||
|
*
|
||||||
|
* Opik requires v7 UUIDs for trace and span IDs. WordPress only provides
|
||||||
|
* wp_generate_uuid4() so we implement v7 here.
|
||||||
|
*
|
||||||
|
* UUID v7 structure (128 bits):
|
||||||
|
* - Bits 0-47 : Unix timestamp in milliseconds (big-endian)
|
||||||
|
* - Bits 48-51 : Version nibble (0x7)
|
||||||
|
* - Bits 52-63 : rand_a (12 random bits)
|
||||||
|
* - Bits 64-65 : Variant (0b10)
|
||||||
|
* - Bits 66-127: rand_b (62 random bits)
|
||||||
|
*
|
||||||
|
* @return string UUID v7 in standard 8-4-4-4-12 hex format.
|
||||||
|
*/
|
||||||
|
private static function generate_uuid7(): string {
|
||||||
|
$ms = (int) ( microtime( true ) * 1000 );
|
||||||
|
$ts_hex = str_pad( dechex( $ms ), 12, '0', STR_PAD_LEFT ); // 48-bit ts -> 12 hex
|
||||||
|
$rand = bin2hex( random_bytes( 10 ) ); // 80 random bits -> 20 hex
|
||||||
|
|
||||||
|
// Group 3: version nibble '7' + 12 random bits (3 hex chars).
|
||||||
|
$g3 = '7' . substr( $rand, 0, 3 );
|
||||||
|
|
||||||
|
// Group 4: variant byte (top 2 bits = 10) + 2 random hex chars.
|
||||||
|
$var_byte = ( hexdec( substr( $rand, 4, 2 ) ) & 0x3f ) | 0x80;
|
||||||
|
$g4 = sprintf( '%02x', $var_byte ) . substr( $rand, 6, 2 );
|
||||||
|
|
||||||
|
// Group 5: 12 remaining random hex chars.
|
||||||
|
$g5 = substr( $rand, 8, 12 );
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'%s-%s-%s-%s-%s',
|
||||||
|
substr( $ts_hex, 0, 8 ), // time_high (32 bits)
|
||||||
|
substr( $ts_hex, 8, 4 ), // time_low (16 bits)
|
||||||
|
$g3,
|
||||||
|
$g4,
|
||||||
|
$g5
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* Plugin Name: PRAutoBlogger
|
* Plugin Name: PRAutoBlogger
|
||||||
* Plugin URI: https://peptiderepo.com/prautoblogger
|
* Plugin URI: https://peptiderepo.com/prautoblogger
|
||||||
* Description: Monitors social media for trending topics, generates SEO-friendly blog posts using AI, and publishes them on a daily schedule with full cost tracking and self-improvement metrics.
|
* Description: Monitors social media for trending topics, generates SEO-friendly blog posts using AI, and publishes them on a daily schedule with full cost tracking and self-improvement metrics.
|
||||||
* Version: 0.12.0
|
* Version: 0.12.1
|
||||||
* Requires at least: 6.0
|
* Requires at least: 6.0
|
||||||
* Requires PHP: 7.4
|
* Requires PHP: 7.4
|
||||||
* Author: PeptideRepo
|
* Author: PeptideRepo
|
||||||
@@ -35,7 +35,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
| Defined here so every file in the plugin can reference paths, versions,
|
| Defined here so every file in the plugin can reference paths, versions,
|
||||||
| and limits without magic strings.
|
| and limits without magic strings.
|
||||||
*/
|
*/
|
||||||
define( 'PRAUTOBLOGGER_VERSION', '0.12.0' );
|
define( 'PRAUTOBLOGGER_VERSION', '0.12.1' );
|
||||||
define( 'PRAUTOBLOGGER_DB_VERSION', '1.1.0' );
|
define( 'PRAUTOBLOGGER_DB_VERSION', '1.1.0' );
|
||||||
define( 'PRAUTOBLOGGER_PLUGIN_FILE', __FILE__ );
|
define( 'PRAUTOBLOGGER_PLUGIN_FILE', __FILE__ );
|
||||||
define( 'PRAUTOBLOGGER_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
define( 'PRAUTOBLOGGER_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
||||||
|
|||||||
Reference in New Issue
Block a user