Skip to content

Commit

Permalink
Receive session.created event once connected
Browse files Browse the repository at this point in the history
  • Loading branch information
thekid committed Oct 27, 2024
1 parent 60c14a0 commit f381478
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 17 deletions.
24 changes: 20 additions & 4 deletions src/main/php/com/openai/realtime/RealtimeApi.class.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<?php namespace com\openai\realtime;

use lang\IllegalStateException;
use text\json\Json;
use util\URI;
use util\data\Marshalling;
use util\log\Traceable;
use util\URI;
use websocket\WebSocket;

/**
Expand All @@ -29,11 +30,26 @@ public function setTrace($cat) {
$this->cat= $cat;
}

/** Opens the underlying websocket, optionally passing headers */
public function connect(array $headers= []): self {
/**
* Opens the underlying websocket, optionally passing headers
*
* Verifies a `session.created` event is received. This is sent by the server
* as soon as the connection is successfully established. Provides a connection-
* specific ID that may be useful for debugging or logging.
*
* @return var
* @throws lang.IllegalStateException
*/
public function connect(array $headers= []) {
$this->cat && $this->cat->info($this->ws->socket(), $this->ws->path(), $headers);
$this->ws->connect($headers);
return $this;

$event= $this->receive();
if ('session.created' === ($event['type'] ?? null)) return $event;

$error= 'Unexpected handshake event "'.($event['type'] ?? '(null)').'"';
$this->ws->close(4007, $error);
throw new IllegalStateException($error);
}

/** Returns whether the underlying websocket is connected */
Expand Down
30 changes: 17 additions & 13 deletions src/test/php/com/openai/unittest/RealtimeApiTest.class.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<?php namespace com\openai\unittest;

use com\openai\realtime\RealtimeApi;
use test\{Assert, Test, Values};
use lang\IllegalStateException;
use test\{Assert, Expect, Test, Values};

class RealtimeApiTest {
const SESSION_CREATED= '{"type": "session.created"}';

/** Returns authentications */
private function authentications(): iterable {
Expand All @@ -25,15 +27,15 @@ public function initially_not_connected() {

#[Test]
public function connect() {
$c= new RealtimeApi(new TestingSocket());
$c= new RealtimeApi(new TestingSocket([self::SESSION_CREATED]));
$c->connect();

Assert::true($c->connected());
}

#[Test, Values(from: 'authentications')]
public function passing_headers($kind, $headers) {
$s= new TestingSocket();
$s= new TestingSocket([self::SESSION_CREATED]);

$c= new RealtimeApi($s);
$c->connect($headers);
Expand All @@ -43,7 +45,7 @@ public function passing_headers($kind, $headers) {

#[Test]
public function close() {
$c= new RealtimeApi(new TestingSocket());
$c= new RealtimeApi(new TestingSocket([self::SESSION_CREATED]));
$c->connect();
$c->close();

Expand All @@ -52,23 +54,26 @@ public function close() {

#[Test]
public function initial_handshake() {
$c= new RealtimeApi(new TestingSocket([
'{"type": "session.created"}',
]));
$c->connect();
$c= new RealtimeApi(new TestingSocket([self::SESSION_CREATED]));
$session= $c->connect();

Assert::equals(['type' => 'session.created'], $session);
}

Assert::equals(['type' => 'session.created'], $c->receive());
#[Test, Expect(class: IllegalStateException::class, message: 'Unexpected handshake event "error"')]
public function unexpected_handshake() {
$c= new RealtimeApi(new TestingSocket(['{"type":"error"}']));
$c->connect();
}

#[Test]
public function update_session() {
$c= new RealtimeApi(new TestingSocket([
'{"type": "session.created"}',
self::SESSION_CREATED,
'{"type": "session.update", "session": {"instructions": "You are TestGPT"}}',
'{"type": "session.updated"}',
]));
$c->connect();
$c->receive();
$c->send(['type' => 'session.update', 'session' => ['instructions' => 'You are TestGPT']]);

Assert::equals(['type' => 'session.updated'], $c->receive());
Expand All @@ -77,12 +82,11 @@ public function update_session() {
#[Test]
public function transmit() {
$c= new RealtimeApi(new TestingSocket([
'{"type": "session.created"}',
self::SESSION_CREATED,
'{"type": "conversation.item.create", "item": {"type": "message"}}',
'{"type": "conversation.item.created"}',
]));
$c->connect();
$c->receive();
$response= $c->transmit(['type' => 'conversation.item.create', 'item' => ['type' => 'message']]);

Assert::equals(['type' => 'conversation.item.created'], $response);
Expand Down

0 comments on commit f381478

Please sign in to comment.