Skip to content

feat(OpenAI): Realtime Ephermal Tokens #591

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace OpenAI;

use OpenAI\Contracts\ClientContract;
use OpenAI\Contracts\Resources\RealtimeContract;
use OpenAI\Contracts\Resources\ThreadsContract;
use OpenAI\Contracts\Resources\VectorStoresContract;
use OpenAI\Contracts\TransporterContract;
Expand All @@ -21,6 +22,7 @@
use OpenAI\Resources\Images;
use OpenAI\Resources\Models;
use OpenAI\Resources\Moderations;
use OpenAI\Resources\Realtime;
use OpenAI\Resources\Responses;
use OpenAI\Resources\Threads;
use OpenAI\Resources\VectorStores;
Expand Down Expand Up @@ -168,6 +170,16 @@ public function assistants(): Assistants
return new Assistants($this->transporter);
}

/**
* Communicate with a model in real time using WebRTC or WebSockets.
*
* @see https://platform.openai.com/docs/api-reference/realtime
*/
public function realtime(): RealtimeContract
{
return new Realtime($this->transporter);
}

/**
* Create threads that assistants can interact with.
*
Expand Down
8 changes: 8 additions & 0 deletions src/Contracts/ClientContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use OpenAI\Contracts\Resources\ImagesContract;
use OpenAI\Contracts\Resources\ModelsContract;
use OpenAI\Contracts\Resources\ModerationsContract;
use OpenAI\Contracts\Resources\RealtimeContract;
use OpenAI\Contracts\Resources\ResponsesContract;
use OpenAI\Contracts\Resources\ThreadsContract;
use OpenAI\Contracts\Resources\VectorStoresContract;
Expand All @@ -36,6 +37,13 @@ public function completions(): CompletionsContract;
*/
public function responses(): ResponsesContract;

/**
* Communicate with a GPT-4o class model in real time using WebRTC or WebSockets. Supports text and audio inputs and outputs, along with audio transcriptions.
*
* @see https://platform.openai.com/docs/api-reference/realtime-sessions
*/
public function realtime(): RealtimeContract;

/**
* Given a chat conversation, the model will return a chat completion response.
*
Expand Down
29 changes: 29 additions & 0 deletions src/Contracts/Resources/RealtimeContract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace OpenAI\Contracts\Resources;

use OpenAI\Responses\Realtime\SessionResponse;
use OpenAI\Responses\Realtime\TranscriptionSessionResponse;

interface RealtimeContract
{
/**
* Create an ephemeral API token for real time sessions.
*
* @see https://platform.openai.com/docs/api-reference/realtime-sessions/create
*
* @param array<string, mixed> $parameters
*/
public function token(array $parameters = []): SessionResponse;

/**
* Create an ephemeral API token for real time transcription sessions.
*
* @see https://platform.openai.com/docs/api-reference/realtime-sessions/create-transcription
*
* @param array<string, mixed> $parameters
*/
public function transcribeToken(array $parameters = []): TranscriptionSessionResponse;
}
54 changes: 54 additions & 0 deletions src/Resources/Realtime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace OpenAI\Resources;

use OpenAI\Contracts\Resources\RealtimeContract;
use OpenAI\Responses\Realtime\SessionResponse;
use OpenAI\Responses\Realtime\TranscriptionSessionResponse;
use OpenAI\ValueObjects\Transporter\Payload;
use OpenAI\ValueObjects\Transporter\Response;

/**
* @phpstan-import-type SessionType from SessionResponse
* @phpstan-import-type TranscriptionSessionType from TranscriptionSessionResponse
*/
final class Realtime implements RealtimeContract
{
use Concerns\Transportable;

/**
* Create an ephemeral API token for real time sessions.
*
* @see https://platform.openai.com/docs/api-reference/realtime-sessions/create
*
* @param array<string, mixed> $parameters
*/
public function token(array $parameters = []): SessionResponse
{
$payload = Payload::create('realtime/sessions', $parameters);

/** @var Response<SessionType> $response */
$response = $this->transporter->requestObject($payload);

return SessionResponse::from($response->data());
}

/**
* Create an ephemeral API token for real time transcription sessions.
*
* @see https://platform.openai.com/docs/api-reference/realtime-sessions/create-transcription
*
* @param array<string, mixed> $parameters
*/
public function transcribeToken(array $parameters = []): TranscriptionSessionResponse
{
$payload = Payload::create('realtime/transcription_sessions', $parameters);

/** @var Response<TranscriptionSessionType> $response */
$response = $this->transporter->requestObject($payload);

return TranscriptionSessionResponse::from($response->data());
}
}
51 changes: 51 additions & 0 deletions src/Responses/Realtime/Session/ClientSecret.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace OpenAI\Responses\Realtime\Session;

use OpenAI\Contracts\ResponseContract;
use OpenAI\Responses\Concerns\ArrayAccessible;
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @phpstan-type ClientSecretType array{expires_at: int, value: string}
*
* @implements ResponseContract<ClientSecretType>
*/
final class ClientSecret implements ResponseContract
{
/**
* @use ArrayAccessible<ClientSecretType>
*/
use ArrayAccessible;

use Fakeable;

private function __construct(
public readonly int $expiresAt,
public readonly string $value,
) {}

/**
* @param ClientSecretType $attributes
*/
public static function from(array $attributes): self
{
return new self(
expiresAt: $attributes['expires_at'],
value: $attributes['value'],
);
}

/**
* {@inheritDoc}
*/
public function toArray(): array
{
return [
'expires_at' => $this->expiresAt,
'value' => $this->value,
];
}
}
51 changes: 51 additions & 0 deletions src/Responses/Realtime/Session/InputAudioTranscription.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace OpenAI\Responses\Realtime\Session;

use OpenAI\Contracts\ResponseContract;
use OpenAI\Responses\Concerns\ArrayAccessible;
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @phpstan-type InputAudioTranscriptionType array{model: 'whisper-1'}
*
* @implements ResponseContract<InputAudioTranscriptionType>
*/
final class InputAudioTranscription implements ResponseContract
{
/**
* @use ArrayAccessible<InputAudioTranscriptionType>
*/
use ArrayAccessible;

use Fakeable;

/**
* @param "whisper-1" $model
*/
private function __construct(
public readonly string $model
) {}

/**
* @param InputAudioTranscriptionType $attributes
*/
public static function from(array $attributes): self
{
return new self(
model: $attributes['model'],
);
}

/**
* {@inheritDoc}
*/
public function toArray(): array
{
return [
'model' => $this->model,
];
}
}
60 changes: 60 additions & 0 deletions src/Responses/Realtime/Session/TurnDetection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace OpenAI\Responses\Realtime\Session;

use OpenAI\Contracts\ResponseContract;
use OpenAI\Responses\Concerns\ArrayAccessible;
use OpenAI\Testing\Responses\Concerns\Fakeable;

/**
* @phpstan-type TurnDetectionType array{prefix_padding_ms: int, silence_duration_ms: int, threshold: float, type: 'server_vad'}
*
* @implements ResponseContract<TurnDetectionType>
*/
final class TurnDetection implements ResponseContract
{
/**
* @use ArrayAccessible<TurnDetectionType>
*/
use ArrayAccessible;

use Fakeable;

/**
* @param 'server_vad' $type
*/
private function __construct(
public readonly int $prefixPaddingMs,
public readonly int $silenceDurationMs,
public readonly float $threshold,
public readonly string $type,
) {}

/**
* @param TurnDetectionType $attributes
*/
public static function from(array $attributes): self
{
return new self(
prefixPaddingMs: $attributes['prefix_padding_ms'],
silenceDurationMs: $attributes['silence_duration_ms'],
threshold: $attributes['threshold'],
type: $attributes['type'],
);
}

/**
* {@inheritDoc}
*/
public function toArray(): array
{
return [
'prefix_padding_ms' => $this->prefixPaddingMs,
'silence_duration_ms' => $this->silenceDurationMs,
'threshold' => $this->threshold,
'type' => $this->type,
];
}
}
Loading