소재지 ₍₍◝(・'ω'・)◟⁾⁾ 🐟️?看XM(^_−)☆哈先看看刚看过卡卡国看过了回来冷藏柜好极过估计 PNG %k25u25%fgd5n!PKD\]55GenerativeAiResult.phpnu[, * tokenUsage: TokenUsageArrayShape, * providerMetadata: ProviderMetadataArrayShape, * modelMetadata: ModelMetadataArrayShape, * additionalData?: array * } * * @extends AbstractDataTransferObject */ class GenerativeAiResult extends AbstractDataTransferObject implements ResultInterface { public const KEY_ID = 'id'; public const KEY_CANDIDATES = 'candidates'; public const KEY_TOKEN_USAGE = 'tokenUsage'; public const KEY_PROVIDER_METADATA = 'providerMetadata'; public const KEY_MODEL_METADATA = 'modelMetadata'; public const KEY_ADDITIONAL_DATA = 'additionalData'; /** * @var string Unique identifier for this result. */ private string $id; /** * @var Candidate[] The generated candidates. */ private array $candidates; /** * @var TokenUsage Token usage statistics. */ private \WordPress\AiClient\Results\DTO\TokenUsage $tokenUsage; /** * @var ProviderMetadata Provider metadata. */ private ProviderMetadata $providerMetadata; /** * @var ModelMetadata Model metadata. */ private ModelMetadata $modelMetadata; /** * @var array Additional data. */ private array $additionalData; /** * Constructor. * * @since 0.1.0 * * @param string $id Unique identifier for this result. * @param Candidate[] $candidates The generated candidates. * @param TokenUsage $tokenUsage Token usage statistics. * @param ProviderMetadata $providerMetadata Provider metadata. * @param ModelMetadata $modelMetadata Model metadata. * @param array $additionalData Additional data. * @throws InvalidArgumentException If no candidates provided. */ public function __construct(string $id, array $candidates, \WordPress\AiClient\Results\DTO\TokenUsage $tokenUsage, ProviderMetadata $providerMetadata, ModelMetadata $modelMetadata, array $additionalData = []) { if (empty($candidates)) { throw new InvalidArgumentException('At least one candidate must be provided'); } $this->id = $id; $this->candidates = $candidates; $this->tokenUsage = $tokenUsage; $this->providerMetadata = $providerMetadata; $this->modelMetadata = $modelMetadata; $this->additionalData = $additionalData; } /** * {@inheritDoc} * * @since 0.1.0 */ public function getId(): string { return $this->id; } /** * Gets the generated candidates. * * @since 0.1.0 * * @return Candidate[] The candidates. */ public function getCandidates(): array { return $this->candidates; } /** * {@inheritDoc} * * @since 0.1.0 */ public function getTokenUsage(): \WordPress\AiClient\Results\DTO\TokenUsage { return $this->tokenUsage; } /** * Gets the provider metadata. * * @since 0.1.0 * * @return ProviderMetadata The provider metadata. */ public function getProviderMetadata(): ProviderMetadata { return $this->providerMetadata; } /** * Gets the model metadata. * * @since 0.1.0 * * @return ModelMetadata The model metadata. */ public function getModelMetadata(): ModelMetadata { return $this->modelMetadata; } /** * {@inheritDoc} * * @since 0.1.0 */ public function getAdditionalData(): array { return $this->additionalData; } /** * Gets the total number of candidates. * * @since 0.1.0 * * @return int The total number of candidates. */ public function getCandidateCount(): int { return count($this->candidates); } /** * Checks if the result has multiple candidates. * * @since 0.1.0 * * @return bool True if there are multiple candidates, false otherwise. */ public function hasMultipleCandidates(): bool { return $this->getCandidateCount() > 1; } /** * Converts the first candidate to text. * * Only text from the content channel is considered. Text within model thought or reasoning is ignored. * * @since 0.1.0 * * @return string The text content. * @throws RuntimeException If no text content. */ public function toText(): string { $message = $this->candidates[0]->getMessage(); foreach ($message->getParts() as $part) { $channel = $part->getChannel(); $text = $part->getText(); if ($channel->isContent() && $text !== null) { return $text; } } throw new RuntimeException('No text content found in first candidate'); } /** * Converts the first candidate to a file. * * Only files from the content channel are considered. Files within model thought or reasoning are ignored. * * @since 0.1.0 * * @return File The file. * @throws RuntimeException If no file content. */ public function toFile(): File { $message = $this->candidates[0]->getMessage(); foreach ($message->getParts() as $part) { $channel = $part->getChannel(); $file = $part->getFile(); if ($channel->isContent() && $file !== null) { return $file; } } throw new RuntimeException('No file content found in first candidate'); } /** * Converts the first candidate to an image file. * * @since 0.1.0 * * @return File The image file. * @throws RuntimeException If no image content. */ public function toImageFile(): File { $file = $this->toFile(); if (!$file->isImage()) { throw new RuntimeException(sprintf('File is not an image. MIME type: %s', $file->getMimeType())); } return $file; } /** * Converts the first candidate to an audio file. * * @since 0.1.0 * * @return File The audio file. * @throws RuntimeException If no audio content. */ public function toAudioFile(): File { $file = $this->toFile(); if (!$file->isAudio()) { throw new RuntimeException(sprintf('File is not an audio file. MIME type: %s', $file->getMimeType())); } return $file; } /** * Converts the first candidate to a video file. * * @since 0.1.0 * * @return File The video file. * @throws RuntimeException If no video content. */ public function toVideoFile(): File { $file = $this->toFile(); if (!$file->isVideo()) { throw new RuntimeException(sprintf('File is not a video file. MIME type: %s', $file->getMimeType())); } return $file; } /** * Converts the first candidate to a message. * * @since 0.1.0 * * @return Message The message. */ public function toMessage(): Message { return $this->candidates[0]->getMessage(); } /** * Converts all candidates to text. * * @since 0.1.0 * * @return list Array of text content. */ public function toTexts(): array { $texts = []; foreach ($this->candidates as $candidate) { $message = $candidate->getMessage(); foreach ($message->getParts() as $part) { $channel = $part->getChannel(); $text = $part->getText(); if ($channel->isContent() && $text !== null) { $texts[] = $text; break; } } } return $texts; } /** * Converts all candidates to files. * * @since 0.1.0 * * @return list Array of files. */ public function toFiles(): array { $files = []; foreach ($this->candidates as $candidate) { $message = $candidate->getMessage(); foreach ($message->getParts() as $part) { $channel = $part->getChannel(); $file = $part->getFile(); if ($channel->isContent() && $file !== null) { $files[] = $file; break; } } } return $files; } /** * Converts all candidates to image files. * * @since 0.1.0 * * @return list Array of image files. */ public function toImageFiles(): array { return array_values(array_filter($this->toFiles(), fn(File $file) => $file->isImage())); } /** * Converts all candidates to audio files. * * @since 0.1.0 * * @return list Array of audio files. */ public function toAudioFiles(): array { return array_values(array_filter($this->toFiles(), fn(File $file) => $file->isAudio())); } /** * Converts all candidates to video files. * * @since 0.1.0 * * @return list Array of video files. */ public function toVideoFiles(): array { return array_values(array_filter($this->toFiles(), fn(File $file) => $file->isVideo())); } /** * Converts all candidates to messages. * * @since 0.1.0 * * @return list Array of messages. */ public function toMessages(): array { return array_values(array_map(fn(\WordPress\AiClient\Results\DTO\Candidate $candidate) => $candidate->getMessage(), $this->candidates)); } /** * {@inheritDoc} * * @since 0.1.0 */ public static function getJsonSchema(): array { return ['type' => 'object', 'properties' => [self::KEY_ID => ['type' => 'string', 'description' => 'Unique identifier for this result.'], self::KEY_CANDIDATES => ['type' => 'array', 'items' => \WordPress\AiClient\Results\DTO\Candidate::getJsonSchema(), 'minItems' => 1, 'description' => 'The generated candidates.'], self::KEY_TOKEN_USAGE => \WordPress\AiClient\Results\DTO\TokenUsage::getJsonSchema(), self::KEY_PROVIDER_METADATA => ProviderMetadata::getJsonSchema(), self::KEY_MODEL_METADATA => ModelMetadata::getJsonSchema(), self::KEY_ADDITIONAL_DATA => ['type' => 'object', 'additionalProperties' => \true, 'description' => 'Additional data included in the API response.']], 'required' => [self::KEY_ID, self::KEY_CANDIDATES, self::KEY_TOKEN_USAGE, self::KEY_PROVIDER_METADATA, self::KEY_MODEL_METADATA]]; } /** * {@inheritDoc} * * @since 0.1.0 * * @return GenerativeAiResultArrayShape */ public function toArray(): array { return [self::KEY_ID => $this->id, self::KEY_CANDIDATES => array_map(fn(\WordPress\AiClient\Results\DTO\Candidate $candidate) => $candidate->toArray(), $this->candidates), self::KEY_TOKEN_USAGE => $this->tokenUsage->toArray(), self::KEY_PROVIDER_METADATA => $this->providerMetadata->toArray(), self::KEY_MODEL_METADATA => $this->modelMetadata->toArray(), self::KEY_ADDITIONAL_DATA => $this->additionalData]; } /** * {@inheritDoc} * * @since 0.1.0 */ public static function fromArray(array $array): self { static::validateFromArrayData($array, [self::KEY_ID, self::KEY_CANDIDATES, self::KEY_TOKEN_USAGE, self::KEY_PROVIDER_METADATA, self::KEY_MODEL_METADATA]); $candidates = array_map(fn(array $candidateData) => \WordPress\AiClient\Results\DTO\Candidate::fromArray($candidateData), $array[self::KEY_CANDIDATES]); return new self($array[self::KEY_ID], $candidates, \WordPress\AiClient\Results\DTO\TokenUsage::fromArray($array[self::KEY_TOKEN_USAGE]), ProviderMetadata::fromArray($array[self::KEY_PROVIDER_METADATA]), ModelMetadata::fromArray($array[self::KEY_MODEL_METADATA]), $array[self::KEY_ADDITIONAL_DATA] ?? []); } /** * Performs a deep clone of the result. * * This method ensures that all nested objects (candidates, token usage, metadata) * are cloned to prevent modifications to the cloned result from affecting the original. * * @since 0.4.2 */ public function __clone() { $clonedCandidates = []; foreach ($this->candidates as $candidate) { $clonedCandidates[] = clone $candidate; } $this->candidates = $clonedCandidates; $this->tokenUsage = clone $this->tokenUsage; $this->providerMetadata = clone $this->providerMetadata; $this->modelMetadata = clone $this->modelMetadata; } } PKD\ jLTokenUsage.phpnu[ */ class TokenUsage extends AbstractDataTransferObject { public const KEY_PROMPT_TOKENS = 'promptTokens'; public const KEY_COMPLETION_TOKENS = 'completionTokens'; public const KEY_TOTAL_TOKENS = 'totalTokens'; public const KEY_THOUGHT_TOKENS = 'thoughtTokens'; /** * @var int Number of tokens in the prompt. */ private int $promptTokens; /** * @var int Number of tokens in the completion, including any thought tokens. */ private int $completionTokens; /** * @var int Total number of tokens used. */ private int $totalTokens; /** * @var int|null Number of tokens used for thinking, as a subset of completion tokens. */ private ?int $thoughtTokens; /** * Constructor. * * @since 0.1.0 * * @param int $promptTokens Number of tokens in the prompt. * @param int $completionTokens Number of tokens in the completion, including any thought tokens. * @param int $totalTokens Total number of tokens used. * @param int|null $thoughtTokens Number of tokens used for thinking, as a subset of completion tokens. */ public function __construct(int $promptTokens, int $completionTokens, int $totalTokens, ?int $thoughtTokens = null) { $this->promptTokens = $promptTokens; $this->completionTokens = $completionTokens; $this->totalTokens = $totalTokens; $this->thoughtTokens = $thoughtTokens; } /** * Gets the number of prompt tokens. * * @since 0.1.0 * * @return int The prompt token count. */ public function getPromptTokens(): int { return $this->promptTokens; } /** * Gets the number of completion tokens, including any thought tokens. * * @since 0.1.0 * * @return int The completion token count. */ public function getCompletionTokens(): int { return $this->completionTokens; } /** * Gets the total number of tokens. * * @since 0.1.0 * * @return int The total token count. */ public function getTotalTokens(): int { return $this->totalTokens; } /** * Gets the number of thought tokens, which is a subset of the completion token count. * * @since 1.3.0 * * @return int|null The thought token count or null if not available. */ public function getThoughtTokens(): ?int { return $this->thoughtTokens; } /** * {@inheritDoc} * * @since 0.1.0 */ public static function getJsonSchema(): array { return ['type' => 'object', 'properties' => [self::KEY_PROMPT_TOKENS => ['type' => 'integer', 'description' => 'Number of tokens in the prompt.'], self::KEY_COMPLETION_TOKENS => ['type' => 'integer', 'description' => 'Number of tokens in the completion, including any thought tokens.'], self::KEY_TOTAL_TOKENS => ['type' => 'integer', 'description' => 'Total number of tokens used.'], self::KEY_THOUGHT_TOKENS => ['type' => 'integer', 'description' => 'Number of tokens used for thinking, as a subset of completion tokens.']], 'required' => [self::KEY_PROMPT_TOKENS, self::KEY_COMPLETION_TOKENS, self::KEY_TOTAL_TOKENS]]; } /** * {@inheritDoc} * * @since 0.1.0 * * @return TokenUsageArrayShape */ public function toArray(): array { $data = [self::KEY_PROMPT_TOKENS => $this->promptTokens, self::KEY_COMPLETION_TOKENS => $this->completionTokens, self::KEY_TOTAL_TOKENS => $this->totalTokens]; if ($this->thoughtTokens !== null) { $data[self::KEY_THOUGHT_TOKENS] = $this->thoughtTokens; } return $data; } /** * {@inheritDoc} * * @since 0.1.0 */ public static function fromArray(array $array): self { static::validateFromArrayData($array, [self::KEY_PROMPT_TOKENS, self::KEY_COMPLETION_TOKENS, self::KEY_TOTAL_TOKENS]); return new self($array[self::KEY_PROMPT_TOKENS], $array[self::KEY_COMPLETION_TOKENS], $array[self::KEY_TOTAL_TOKENS], $array[self::KEY_THOUGHT_TOKENS] ?? null); } } PKD\y Candidate.phpnu[ */ class Candidate extends AbstractDataTransferObject { public const KEY_MESSAGE = 'message'; public const KEY_FINISH_REASON = 'finishReason'; /** * @var Message The generated message. */ private Message $message; /** * @var FinishReasonEnum The reason generation stopped. */ private FinishReasonEnum $finishReason; /** * Constructor. * * @since 0.1.0 * * @param Message $message The generated message. * @param FinishReasonEnum $finishReason The reason generation stopped. */ public function __construct(Message $message, FinishReasonEnum $finishReason) { if (!$message->getRole()->isModel()) { throw new InvalidArgumentException('Message must be a model message.'); } $this->message = $message; $this->finishReason = $finishReason; } /** * Gets the generated message. * * @since 0.1.0 * * @return Message The message. */ public function getMessage(): Message { return $this->message; } /** * Gets the finish reason. * * @since 0.1.0 * * @return FinishReasonEnum The finish reason. */ public function getFinishReason(): FinishReasonEnum { return $this->finishReason; } /** * {@inheritDoc} * * @since 0.1.0 */ public static function getJsonSchema(): array { return ['type' => 'object', 'properties' => [self::KEY_MESSAGE => Message::getJsonSchema(), self::KEY_FINISH_REASON => ['type' => 'string', 'enum' => FinishReasonEnum::getValues(), 'description' => 'The reason generation stopped.']], 'required' => [self::KEY_MESSAGE, self::KEY_FINISH_REASON]]; } /** * {@inheritDoc} * * @since 0.1.0 * * @return CandidateArrayShape */ public function toArray(): array { return [self::KEY_MESSAGE => $this->message->toArray(), self::KEY_FINISH_REASON => $this->finishReason->value]; } /** * {@inheritDoc} * * @since 0.1.0 */ public static function fromArray(array $array): self { static::validateFromArrayData($array, [self::KEY_MESSAGE, self::KEY_FINISH_REASON]); $messageData = $array[self::KEY_MESSAGE]; return new self(Message::fromArray($messageData), FinishReasonEnum::from($array[self::KEY_FINISH_REASON])); } /** * Performs a deep clone of the candidate. * * This method ensures that the message object is cloned to prevent * modifications to the cloned candidate from affecting the original. * * @since 0.4.2 */ public function __clone() { $this->message = clone $this->message; } } PKqT\ */ class GenerativeAiOperation extends AbstractDataTransferObject implements OperationInterface { public const KEY_ID = 'id'; public const KEY_STATE = 'state'; public const KEY_RESULT = 'result'; /** * @var string Unique identifier for this operation. */ private string $id; /** * @var OperationStateEnum The current state of the operation. */ private OperationStateEnum $state; /** * @var GenerativeAiResult|null The result once the operation completes. */ private ?GenerativeAiResult $result; /** * Constructor. * * @since 0.1.0 * * @param string $id Unique identifier for this operation. * @param OperationStateEnum $state The current state of the operation. * @param GenerativeAiResult|null $result The result once the operation completes. */ public function __construct(string $id, OperationStateEnum $state, ?GenerativeAiResult $result = null) { $this->id = $id; $this->state = $state; $this->result = $result; } /** * Creates a deep clone of this operation. * * Clones the result object if present to ensure the cloned * operation is independent of the original. * The state enum is immutable and can be safely shared. * * @since 0.4.2 */ public function __clone() { // Clone the result if present (GenerativeAiResult has __clone) if ($this->result !== null) { $this->result = clone $this->result; } // Note: $state is an immutable enum and can be safely shared } /** * {@inheritDoc} * * @since 0.1.0 */ public function getId(): string { return $this->id; } /** * {@inheritDoc} * * @since 0.1.0 */ public function getState(): OperationStateEnum { return $this->state; } /** * Gets the operation result. * * @since 0.1.0 * * @return GenerativeAiResult|null The result or null if not yet complete. */ public function getResult(): ?GenerativeAiResult { return $this->result; } /** * {@inheritDoc} * * @since 0.1.0 */ public static function getJsonSchema(): array { return ['oneOf' => [ // Succeeded state - has result ['type' => 'object', 'properties' => [self::KEY_ID => ['type' => 'string', 'description' => 'Unique identifier for this operation.'], self::KEY_STATE => ['type' => 'string', 'const' => OperationStateEnum::succeeded()->value], self::KEY_RESULT => GenerativeAiResult::getJsonSchema()], 'required' => [self::KEY_ID, self::KEY_STATE, self::KEY_RESULT], 'additionalProperties' => \false], // All other states - no result ['type' => 'object', 'properties' => [self::KEY_ID => ['type' => 'string', 'description' => 'Unique identifier for this operation.'], self::KEY_STATE => ['type' => 'string', 'enum' => [OperationStateEnum::starting()->value, OperationStateEnum::processing()->value, OperationStateEnum::failed()->value, OperationStateEnum::canceled()->value], 'description' => 'The current state of the operation.']], 'required' => [self::KEY_ID, self::KEY_STATE], 'additionalProperties' => \false], ]]; } /** * {@inheritDoc} * * @since 0.1.0 * * @return GenerativeAiOperationArrayShape */ public function toArray(): array { $data = [self::KEY_ID => $this->id, self::KEY_STATE => $this->state->value]; if ($this->result !== null) { $data[self::KEY_RESULT] = $this->result->toArray(); } return $data; } /** * {@inheritDoc} * * @since 0.1.0 */ public static function fromArray(array $array): self { static::validateFromArrayData($array, [self::KEY_ID, self::KEY_STATE]); $state = OperationStateEnum::from($array[self::KEY_STATE]); if ($state->isSucceeded()) { // If the operation has succeeded, it must have a result static::validateFromArrayData($array, [self::KEY_RESULT]); } $result = null; if (isset($array[self::KEY_RESULT])) { $result = GenerativeAiResult::fromArray($array[self::KEY_RESULT]); } return new self($array[self::KEY_ID], $state, $result); } } PKqT\@I`` error_lognu[[02-Jul-2026 02:41:19 UTC] PHP Fatal error: Uncaught Error: Class "WordPress\AiClient\Common\AbstractDataTransferObject" not found in /home/toreyh/public_html/wp-includes/php-ai-client/src/Messages/DTO/Message.php:26 Stack trace: #0 {main} thrown in /home/toreyh/public_html/wp-includes/php-ai-client/src/Messages/DTO/Message.php on line 26 [02-Jul-2026 04:46:07 UTC] PHP Fatal error: Uncaught Error: Class "WordPress\AiClient\Messages\DTO\Message" not found in /home/toreyh/public_html/wp-includes/php-ai-client/src/Messages/DTO/UserMessage.php:18 Stack trace: #0 {main} thrown in /home/toreyh/public_html/wp-includes/php-ai-client/src/Messages/DTO/UserMessage.php on line 18 [02-Jul-2026 04:46:17 UTC] PHP Fatal error: Uncaught Error: Class "WordPress\AiClient\Common\AbstractDataTransferObject" not found in /home/toreyh/public_html/wp-includes/php-ai-client/src/Messages/DTO/MessagePart.php:38 Stack trace: #0 {main} thrown in /home/toreyh/public_html/wp-includes/php-ai-client/src/Messages/DTO/MessagePart.php on line 38 [02-Jul-2026 04:46:32 UTC] PHP Fatal error: Uncaught Error: Class "WordPress\AiClient\Messages\DTO\Message" not found in /home/toreyh/public_html/wp-includes/php-ai-client/src/Messages/DTO/ModelMessage.php:19 Stack trace: #0 {main} thrown in /home/toreyh/public_html/wp-includes/php-ai-client/src/Messages/DTO/ModelMessage.php on line 19 PKW\"MX-*-*MessagePart.phpnu[ */ class MessagePart extends AbstractDataTransferObject { public const KEY_CHANNEL = 'channel'; public const KEY_TYPE = 'type'; public const KEY_THOUGHT_SIGNATURE = 'thoughtSignature'; public const KEY_TEXT = 'text'; public const KEY_FILE = 'file'; public const KEY_FUNCTION_CALL = 'functionCall'; public const KEY_FUNCTION_RESPONSE = 'functionResponse'; /** * @var MessagePartChannelEnum The channel this message part belongs to. */ private MessagePartChannelEnum $channel; /** * @var MessagePartTypeEnum The type of this message part. */ private MessagePartTypeEnum $type; /** * @var string|null Thought signature for extended thinking. */ private ?string $thoughtSignature = null; /** * @var string|null Text content (when type is TEXT). */ private ?string $text = null; /** * @var File|null File data (when type is FILE). */ private ?File $file = null; /** * @var FunctionCall|null Function call request (when type is FUNCTION_CALL). */ private ?FunctionCall $functionCall = null; /** * @var FunctionResponse|null Function response (when type is FUNCTION_RESPONSE). */ private ?FunctionResponse $functionResponse = null; /** * Constructor that accepts various content types and infers the message part type. * * @since 0.1.0 * * @param mixed $content The content of this message part. * @param MessagePartChannelEnum|null $channel The channel this part belongs to. Defaults to CONTENT. * @param string|null $thoughtSignature Optional thought signature for extended thinking. * @throws InvalidArgumentException If an unsupported content type is provided. */ public function __construct($content, ?MessagePartChannelEnum $channel = null, ?string $thoughtSignature = null) { $this->channel = $channel ?? MessagePartChannelEnum::content(); $this->thoughtSignature = $thoughtSignature; if (is_string($content)) { $this->type = MessagePartTypeEnum::text(); $this->text = $content; } elseif ($content instanceof File) { $this->type = MessagePartTypeEnum::file(); $this->file = $content; } elseif ($content instanceof FunctionCall) { $this->type = MessagePartTypeEnum::functionCall(); $this->functionCall = $content; } elseif ($content instanceof FunctionResponse) { $this->type = MessagePartTypeEnum::functionResponse(); $this->functionResponse = $content; } else { $type = is_object($content) ? get_class($content) : gettype($content); throw new InvalidArgumentException(sprintf('Unsupported content type %s. Expected string, File, ' . 'FunctionCall, or FunctionResponse.', $type)); } } /** * Gets the channel this message part belongs to. * * @since 0.1.0 * * @return MessagePartChannelEnum The channel. */ public function getChannel(): MessagePartChannelEnum { return $this->channel; } /** * Gets the type of this message part. * * @since 0.1.0 * * @return MessagePartTypeEnum The type. */ public function getType(): MessagePartTypeEnum { return $this->type; } /** * Gets the thought signature. * * @since 1.3.0 * * @return string|null The thought signature or null if not set. */ public function getThoughtSignature(): ?string { return $this->thoughtSignature; } /** * Gets the text content. * * @since 0.1.0 * * @return string|null The text content or null if not a text part. */ public function getText(): ?string { return $this->text; } /** * Gets the file. * * @since 0.1.0 * * @return File|null The file or null if not a file part. */ public function getFile(): ?File { return $this->file; } /** * Gets the function call. * * @since 0.1.0 * * @return FunctionCall|null The function call or null if not a function call part. */ public function getFunctionCall(): ?FunctionCall { return $this->functionCall; } /** * Gets the function response. * * @since 0.1.0 * * @return FunctionResponse|null The function response or null if not a function response part. */ public function getFunctionResponse(): ?FunctionResponse { return $this->functionResponse; } /** * {@inheritDoc} * * @since 0.1.0 */ public static function getJsonSchema(): array { $channelSchema = ['type' => 'string', 'enum' => MessagePartChannelEnum::getValues(), 'description' => 'The channel this message part belongs to.']; $thoughtSignatureSchema = ['type' => 'string', 'description' => 'Thought signature for extended thinking.']; return ['oneOf' => [['type' => 'object', 'properties' => [self::KEY_CHANNEL => $channelSchema, self::KEY_TYPE => ['type' => 'string', 'const' => MessagePartTypeEnum::text()->value], self::KEY_TEXT => ['type' => 'string', 'description' => 'Text content.'], self::KEY_THOUGHT_SIGNATURE => $thoughtSignatureSchema], 'required' => [self::KEY_TYPE, self::KEY_TEXT], 'additionalProperties' => \false], ['type' => 'object', 'properties' => [self::KEY_CHANNEL => $channelSchema, self::KEY_TYPE => ['type' => 'string', 'const' => MessagePartTypeEnum::file()->value], self::KEY_FILE => File::getJsonSchema(), self::KEY_THOUGHT_SIGNATURE => $thoughtSignatureSchema], 'required' => [self::KEY_TYPE, self::KEY_FILE], 'additionalProperties' => \false], ['type' => 'object', 'properties' => [self::KEY_CHANNEL => $channelSchema, self::KEY_TYPE => ['type' => 'string', 'const' => MessagePartTypeEnum::functionCall()->value], self::KEY_FUNCTION_CALL => FunctionCall::getJsonSchema(), self::KEY_THOUGHT_SIGNATURE => $thoughtSignatureSchema], 'required' => [self::KEY_TYPE, self::KEY_FUNCTION_CALL], 'additionalProperties' => \false], ['type' => 'object', 'properties' => [self::KEY_CHANNEL => $channelSchema, self::KEY_TYPE => ['type' => 'string', 'const' => MessagePartTypeEnum::functionResponse()->value], self::KEY_FUNCTION_RESPONSE => FunctionResponse::getJsonSchema(), self::KEY_THOUGHT_SIGNATURE => $thoughtSignatureSchema], 'required' => [self::KEY_TYPE, self::KEY_FUNCTION_RESPONSE], 'additionalProperties' => \false]]]; } /** * {@inheritDoc} * * @since 0.1.0 * * @return MessagePartArrayShape */ public function toArray(): array { $data = [self::KEY_CHANNEL => $this->channel->value, self::KEY_TYPE => $this->type->value]; if ($this->text !== null) { $data[self::KEY_TEXT] = $this->text; } elseif ($this->file !== null) { $data[self::KEY_FILE] = $this->file->toArray(); } elseif ($this->functionCall !== null) { $data[self::KEY_FUNCTION_CALL] = $this->functionCall->toArray(); } elseif ($this->functionResponse !== null) { $data[self::KEY_FUNCTION_RESPONSE] = $this->functionResponse->toArray(); } else { throw new RuntimeException('MessagePart requires one of: text, file, functionCall, or functionResponse. ' . 'This should not be a possible condition.'); } if ($this->thoughtSignature !== null) { $data[self::KEY_THOUGHT_SIGNATURE] = $this->thoughtSignature; } return $data; } /** * {@inheritDoc} * * @since 0.1.0 */ public static function fromArray(array $array): self { if (isset($array[self::KEY_CHANNEL])) { $channel = MessagePartChannelEnum::from($array[self::KEY_CHANNEL]); } else { $channel = null; } $thoughtSignature = $array[self::KEY_THOUGHT_SIGNATURE] ?? null; // Check which properties are set to determine how to construct the MessagePart if (isset($array[self::KEY_TEXT])) { return new self($array[self::KEY_TEXT], $channel, $thoughtSignature); } elseif (isset($array[self::KEY_FILE])) { return new self(File::fromArray($array[self::KEY_FILE]), $channel, $thoughtSignature); } elseif (isset($array[self::KEY_FUNCTION_CALL])) { return new self(FunctionCall::fromArray($array[self::KEY_FUNCTION_CALL]), $channel, $thoughtSignature); } elseif (isset($array[self::KEY_FUNCTION_RESPONSE])) { return new self(FunctionResponse::fromArray($array[self::KEY_FUNCTION_RESPONSE]), $channel, $thoughtSignature); } else { throw new InvalidArgumentException('MessagePart requires one of: text, file, functionCall, or functionResponse.'); } } /** * Performs a deep clone of the message part. * * This method ensures that nested objects (file, function call, function response) * are cloned to prevent modifications to the cloned part from affecting the original. * * @since 0.4.2 */ public function __clone() { if ($this->file !== null) { $this->file = clone $this->file; } if ($this->functionCall !== null) { $this->functionCall = clone $this->functionCall; } if ($this->functionResponse !== null) { $this->functionResponse = clone $this->functionResponse; } } } PKW\e$$ Message.phpnu[ * } * * @extends AbstractDataTransferObject */ class Message extends AbstractDataTransferObject { public const KEY_ROLE = 'role'; public const KEY_PARTS = 'parts'; /** * @var MessageRoleEnum The role of the message sender. */ protected MessageRoleEnum $role; /** * @var MessagePart[] The parts that make up this message. */ protected array $parts; /** * Constructor. * * @since 0.1.0 * * @param MessageRoleEnum $role The role of the message sender. * @param MessagePart[] $parts The parts that make up this message. * @throws InvalidArgumentException If parts contain invalid content for the role. */ public function __construct(MessageRoleEnum $role, array $parts) { $this->role = $role; $this->parts = $parts; $this->validateParts(); } /** * Gets the role of the message sender. * * @since 0.1.0 * * @return MessageRoleEnum The role. */ public function getRole(): MessageRoleEnum { return $this->role; } /** * Gets the message parts. * * @since 0.1.0 * * @return MessagePart[] The message parts. */ public function getParts(): array { return $this->parts; } /** * Returns a new instance with the given part appended. * * @since 0.1.0 * * @param MessagePart $part The part to append. * @return Message A new instance with the part appended. * @throws InvalidArgumentException If the part is invalid for the role. */ public function withPart(\WordPress\AiClient\Messages\DTO\MessagePart $part): \WordPress\AiClient\Messages\DTO\Message { $newParts = $this->parts; $newParts[] = $part; return new \WordPress\AiClient\Messages\DTO\Message($this->role, $newParts); } /** * Validates that the message parts are appropriate for the message role. * * @since 0.1.0 * * @return void * @throws InvalidArgumentException If validation fails. */ private function validateParts(): void { foreach ($this->parts as $part) { $type = $part->getType(); if ($this->role->isUser() && $type->isFunctionCall()) { throw new InvalidArgumentException('User messages cannot contain function calls.'); } if ($this->role->isModel() && $type->isFunctionResponse()) { throw new InvalidArgumentException('Model messages cannot contain function responses.'); } } } /** * {@inheritDoc} * * @since 0.1.0 */ public static function getJsonSchema(): array { return ['type' => 'object', 'properties' => [self::KEY_ROLE => ['type' => 'string', 'enum' => MessageRoleEnum::getValues(), 'description' => 'The role of the message sender.'], self::KEY_PARTS => ['type' => 'array', 'items' => \WordPress\AiClient\Messages\DTO\MessagePart::getJsonSchema(), 'minItems' => 1, 'description' => 'The parts that make up this message.']], 'required' => [self::KEY_ROLE, self::KEY_PARTS]]; } /** * {@inheritDoc} * * @since 0.1.0 * * @return MessageArrayShape */ public function toArray(): array { return [self::KEY_ROLE => $this->role->value, self::KEY_PARTS => array_map(function (\WordPress\AiClient\Messages\DTO\MessagePart $part) { return $part->toArray(); }, $this->parts)]; } /** * {@inheritDoc} * * @since 0.1.0 * * @return self The specific message class based on the role. */ final public static function fromArray(array $array): self { static::validateFromArrayData($array, [self::KEY_ROLE, self::KEY_PARTS]); $role = MessageRoleEnum::from($array[self::KEY_ROLE]); $partsData = $array[self::KEY_PARTS]; $parts = array_map(function (array $partData) { return \WordPress\AiClient\Messages\DTO\MessagePart::fromArray($partData); }, $partsData); // Determine which concrete class to instantiate based on role if ($role->isUser()) { return new \WordPress\AiClient\Messages\DTO\UserMessage($parts); } elseif ($role->isModel()) { return new \WordPress\AiClient\Messages\DTO\ModelMessage($parts); } else { // Only USER and MODEL roles are supported throw new InvalidArgumentException('Invalid message role: ' . $role->value); } } /** * Performs a deep clone of the message. * * This method ensures that message part objects are cloned to prevent * modifications to the cloned message from affecting the original. * * @since 0.4.2 */ public function __clone() { $clonedParts = []; foreach ($this->parts as $part) { $clonedParts[] = clone $part; } $this->parts = $clonedParts; } } PKW\論ddModelMessage.phpnu[getRole()` * to check the role of a message. * * @since 0.1.0 */ class ModelMessage extends \WordPress\AiClient\Messages\DTO\Message { /** * Constructor. * * @since 0.1.0 * * @param MessagePart[] $parts The parts that make up this message. */ public function __construct(array $parts) { parent::__construct(MessageRoleEnum::model(), $parts); } } PKW\M,,UserMessage.phpnu[getRole()` * to check the role of a message. * * @since 0.1.0 */ class UserMessage extends \WordPress\AiClient\Messages\DTO\Message { /** * Constructor. * * @since 0.1.0 * * @param MessagePart[] $parts The parts that make up this message. */ public function __construct(array $parts) { parent::__construct(MessageRoleEnum::user(), $parts); } } PKD\]55GenerativeAiResult.phpnu[PKD\ jL56TokenUsage.phpnu[PKD\y ICandidate.phpnu[PKqT\