https://github.com/bmascat/code-artifact-openai-realtime
React app to generate and preview frontend components by voice (Realtime API OpenAI). It uses the shadcn and tailwindcss libraries by default.
Science Score: 13.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
○CITATION.cff file
-
✓codemeta.json file
Found codemeta.json file -
○.zenodo.json file
-
○DOI references
-
○Academic publication links
-
○Academic email domains
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (12.5%) to scientific vocabulary
Keywords
Repository
React app to generate and preview frontend components by voice (Realtime API OpenAI). It uses the shadcn and tailwindcss libraries by default.
Basic Info
- Host: GitHub
- Owner: bmascat
- License: mit
- Language: TypeScript
- Default Branch: main
- Homepage: https://code-artifact-openai-realtime.vercel.app
- Size: 2.42 MB
Statistics
- Stars: 8
- Watchers: 1
- Forks: 0
- Open Issues: 0
- Releases: 0
Topics
Metadata Files
README.md
Code artifact for OpenAI Realtime API

This project is a fork of the OpenAI Realtime Console project.
Demo
Current Version
OpenAI Realtime Console
The OpenAI Realtime Console is intended as an inspector and interactive API reference
for the OpenAI Realtime API. It comes packaged with two utility libraries,
openai/openai-realtime-api-beta
that acts as a Reference Client (for browser and Node.js) and
/src/lib/wavtools which allows for simple audio
management in the browser.
Code Artifact (Claude artifact inspired)
This version of the Realtime Console implements an adapter artifact component originally developed by Nutlope for the llamacoder project. You can generate and preview react components using shadcn components and tailwindcss. Also perform fetch api calls just with voice. Try to explore further features!
Function call to code generation
As simple as this:
```typescript
client.addTool( { name: 'generatecode', description: 'Generates code based on the user request using shadcn and tailwindcss. Import the shadcn components from /components/ui/{componentname} in lowercase. use fetch to get the data from the api if user mention that feature', parameters: { type: 'object', properties: { code: { type: 'string', description: 'The generated code to be set in the artifact.', }, }, required: ['code'], }, }, async ({ code }: { [key: string]: any }) => {
setGeneratedCode(code);
return { ok: true };
}
);
```
Starting the console
This is a React project created using create-react-app that is bundled via Webpack.
Install it by extracting the contents of this package and using;
shell
$ npm i
Start your server with:
shell
$ npm start
It should be available via localhost:3000.
Table of contents
Using the console
The console requires an OpenAI API key (user key or project key) that has access to the
Realtime API. You'll be prompted on startup to enter it. It will be saved via localStorage and can be
changed at any time from the UI.
To start a session you'll need to connect. This will require microphone access. You can then choose between manual (Push-to-talk) and vad (Voice Activity Detection) conversation modes, and switch between them at any time.
There are two functions enabled;
get_weather: Ask for the weather anywhere and the model will do its best to pinpoint the location, show it on a map, and get the weather for that location. Note that it doesn't have location access, and coordinates are "guessed" from the model's training data so accuracy might not be perfect.set_memory: You can ask the model to remember information for you, and it will store it in a JSON blob on the left.
You can freely interrupt the model at any time in push-to-talk or VAD mode.
Using a relay server
If you would like to build a more robust implementation and play around with the reference client using your own server, we have included a Node.js Relay Server.
shell
$ npm run relay
It will start automatically on localhost:8081.
You will need to create a .env file with the following configuration:
conf
OPENAI_API_KEY=YOUR_API_KEY
REACT_APP_LOCAL_RELAY_SERVER_URL=http://localhost:8081
You will need to restart both your React app and relay server for the .env. changes
to take effect. The local server URL is loaded via ConsolePage.tsx.
To stop using the relay server at any time, simply delete the environment
variable or set it to empty string.
javascript
/**
* Running a local relay server will allow you to hide your API key
* and run custom logic on the server
*
* Set the local relay server address to:
* REACT_APP_LOCAL_RELAY_SERVER_URL=http://localhost:8081
*
* This will also require you to set OPENAI_API_KEY= in a `.env` file
* You can run it with `npm run relay`, in parallel with `npm start`
*/
const LOCAL_RELAY_SERVER_URL: string =
process.env.REACT_APP_LOCAL_RELAY_SERVER_URL || '';
This server is only a simple message relay, but it can be extended to:
- Hide API credentials if you would like to ship an app to play with online
- Handle certain calls you would like to keep secret (e.g.
instructions) on the server directly - Restrict what types of events the client can receive and send
You will have to implement these features yourself.
Realtime API reference client
The latest reference client and documentation are available on GitHub at openai/openai-realtime-api-beta.
You can use this client yourself in any React (front-end) or Node.js project. For full documentation, refer to the GitHub repository, but you can use the guide here as a primer to get started.
```javascript import { RealtimeClient } from '/src/lib/realtime-api-beta/index.js';
const client = new RealtimeClient({ apiKey: process.env.OPENAIAPIKEY });
// Can set parameters ahead of connecting client.updateSession({ instructions: 'You are a great, upbeat friend.' }); client.updateSession({ voice: 'alloy' }); client.updateSession({ turndetection: 'servervad' }); client.updateSession({ inputaudiotranscription: { model: 'whisper-1' } });
// Set up event handling client.on('conversation.updated', ({ item, delta }) => { const items = client.conversation.getItems(); // can use this to render all items /* includes all changes to conversations, delta may be populated */ });
// Connect to Realtime API await client.connect();
// Send an item and triggers a generation
client.sendUserMessageContent([{ type: 'text', text: How are you? }]);
```
Sending streaming audio
To send streaming audio, use the .appendInputAudio() method. If you're in turn_detection: 'disabled' mode,
then you need to use .generate() to tell the model to respond.
javascript
// Send user audio, must be Int16Array or ArrayBuffer
// Default audio format is pcm16 with sample rate of 24,000 Hz
// This populates 1s of noise in 0.1s chunks
for (let i = 0; i < 10; i++) {
const data = new Int16Array(2400);
for (let n = 0; n < 2400; n++) {
const value = Math.floor((Math.random() * 2 - 1) * 0x8000);
data[n] = value;
}
client.appendInputAudio(data);
}
// Pending audio is committed and model is asked to generate
client.createResponse();
Adding and using tools
Working with tools is easy. Just call .addTool() and set a callback as the second parameter.
The callback will be executed with the parameters for the tool, and the result will be automatically
sent back to the model.
javascript
// We can add tools as well, with callbacks specified
client.addTool(
{
name: 'get_weather',
description:
'Retrieves the weather for a given lat, lng coordinate pair. Specify a label for the location.',
parameters: {
type: 'object',
properties: {
lat: {
type: 'number',
description: 'Latitude',
},
lng: {
type: 'number',
description: 'Longitude',
},
location: {
type: 'string',
description: 'Name of the location',
},
},
required: ['lat', 'lng', 'location'],
},
},
async ({ lat, lng, location }) => {
const result = await fetch(
`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lng}¤t=temperature_2m,wind_speed_10m`
);
const json = await result.json();
return json;
}
);
Interrupting the model
You may want to manually interrupt the model, especially in turn_detection: 'disabled' mode.
To do this, we can use:
javascript
// id is the id of the item currently being generated
// sampleCount is the number of audio samples that have been heard by the listener
client.cancelResponse(id, sampleCount);
This method will cause the model to immediately cease generation, but also truncate the
item being played by removing all audio after sampleCount and clearing the text
response. By using this method you can interrupt the model and prevent it from "remembering"
anything it has generated that is ahead of where the user's state is.
Reference client events
There are five main client events for application control flow in RealtimeClient.
Note that this is only an overview of using the client, the full Realtime API
event specification is considerably larger, if you need more control check out the GitHub repository:
openai/openai-realtime-api-beta.
```javascript // errors like connection failures client.on('error', (event) => { // do thing });
// in VAD mode, the user starts speaking // we can use this to stop audio playback of a previous response if necessary client.on('conversation.interrupted', () => { /* do something */ });
// includes all changes to conversations // delta may be populated client.on('conversation.updated', ({ item, delta }) => { // get all items, e.g. if you need to update a chat window const items = client.conversation.getItems(); switch (item.type) { case 'message': // system, user, or assistant message (item.role) break; case 'functioncall': // always a function call from the model break; case 'functioncall_output': // always a response from the user / application break; } if (delta) { // Only one of the following will be populated for any given event // delta.audio = Int16Array, audio added // delta.transcript = string, transcript added // delta.arguments = string, function arguments added } });
// only triggered after item added to conversation client.on('conversation.item.appended', ({ item }) => { /* item status can be 'in_progress' or 'completed' */ });
// only triggered after item completed in conversation // will always be triggered after conversation.item.appended client.on('conversation.item.completed', ({ item }) => { /* item status will always be 'completed' */ }); ```
Wavtools
Wavtools contains easy management of PCM16 audio streams in the browser, both recording and playing.
WavRecorder Quickstart
```javascript import { WavRecorder } from '/src/lib/wavtools/index.js';
const wavRecorder = new WavRecorder({ sampleRate: 24000 }); wavRecorder.getStatus(); // "ended"
// request permissions, connect microphone await wavRecorder.begin(); wavRecorder.getStatus(); // "paused"
// Start recording // This callback will be triggered in chunks of 8192 samples by default // { mono, raw } are Int16Array (PCM16) mono & full channel data await wavRecorder.record((data) => { const { mono, raw } = data; }); wavRecorder.getStatus(); // "recording"
// Stop recording await wavRecorder.pause(); wavRecorder.getStatus(); // "paused"
// outputs "audio/wav" audio file const audio = await wavRecorder.save();
// clears current audio buffer and starts recording await wavRecorder.clear(); await wavRecorder.record();
// get data for visualization const frequencyData = wavRecorder.getFrequencies();
// Stop recording, disconnects microphone, output file await wavRecorder.pause(); const finalAudio = await wavRecorder.end();
// Listen for device change; e.g. if somebody disconnects a microphone
// deviceList is array of MediaDeviceInfo[] + default property
wavRecorder.listenForDeviceChange((deviceList) => {});
```
WavStreamPlayer Quickstart
```javascript import { WavStreamPlayer } from '/src/lib/wavtools/index.js';
const wavStreamPlayer = new WavStreamPlayer({ sampleRate: 24000 });
// Connect to audio output await wavStreamPlayer.connect();
// Create 1s of empty PCM16 audio const audio = new Int16Array(24000); // Queue 3s of audio, will start playing immediately wavStreamPlayer.add16BitPCM(audio, 'my-track'); wavStreamPlayer.add16BitPCM(audio, 'my-track'); wavStreamPlayer.add16BitPCM(audio, 'my-track');
// get data for visualization const frequencyData = wavStreamPlayer.getFrequencies();
// Interrupt the audio (halt playback) at any time // To restart, need to call .add16BitPCM() again const trackOffset = await wavStreamPlayer.interrupt(); trackOffset.trackId; // "my-track" trackOffset.offset; // sample number trackOffset.currentTime; // time in track ```
Acknowledgements and contact
Thanks for checking out the Realtime Console. We hope you have fun with the Realtime API. Special thanks to the whole Realtime API team for making this possible. Please feel free to reach out, ask questions, or give feedback by creating an issue on the repository. You can also reach out and let us know what you think directly!
- OpenAI Developers / @OpenAIDevs
- Jordan Sitkin / API / @dustmason
- Mark Hudnall / API / @landakram
- Peter Bakkum / API / @pbbakkum
- Atty Eleti / API / @athyuttamre
- Jason Clark / API / @onebitToo
- Karolis Kosas / Design / @karoliskosas
- Keith Horwood / API + DX / @keithwhor
- Romain Huet / DX / @romainhuet
- Katia Gil Guzman / DX / @kagigz
- Ilan Bigio / DX / @ilanbigio
- Kevin Whinnery / DX / @kevinwhinnery
Owner
- Name: Brais
- Login: bmascat
- Kind: user
- Repositories: 2
- Profile: https://github.com/bmascat
Data science, bioinformatics and software development
GitHub Events
Total
- Watch event: 4
- Fork event: 2
Last Year
- Watch event: 4
- Fork event: 2
Issues and Pull Requests
Last synced: 11 months ago
All Time
- Total issues: 0
- Total pull requests: 0
- Average time to close issues: N/A
- Average time to close pull requests: N/A
- Total issue authors: 0
- Total pull request authors: 0
- Average comments per issue: 0
- Average comments per pull request: 0
- Merged pull requests: 0
- Bot issues: 0
- Bot pull requests: 0
Past Year
- Issues: 0
- Pull requests: 0
- Average time to close issues: N/A
- Average time to close pull requests: N/A
- Issue authors: 0
- Pull request authors: 0
- Average comments per issue: 0
- Average comments per pull request: 0
- Merged pull requests: 0
- Bot issues: 0
- Bot pull requests: 0
Top Authors
Issue Authors
Pull Request Authors
Top Labels
Issue Labels
Pull Request Labels
Dependencies
- 1337 dependencies
- @babel/plugin-proposal-private-property-in-object ^7.21.11 development
- nodemon ^3.1.7 development
- tailwindcss ^3.4.13 development
- @codesandbox/sandpack-react ^2.19.9
- @codesandbox/sandpack-themes ^2.0.21
- @openai/realtime-api-beta github:openai/openai-realtime-api-beta
- @testing-library/jest-dom ^5.17.0
- @testing-library/react ^13.4.0
- @testing-library/user-event ^13.5.0
- @types/jest ^27.5.2
- @types/leaflet ^1.9.12
- @types/node ^16.18.108
- @types/react ^18.3.5
- @types/react-dom ^18.3.0
- dedent ^1.5.3
- dotenv ^16.4.5
- leaflet ^1.9.4
- openai-realtime-console file:
- react ^18.3.1
- react-dom ^18.3.1
- react-feather ^2.0.10
- react-leaflet ^4.2.1
- react-scripts ^5.0.1
- sass ^1.78.0
- save ^2.9.0
- typescript ^4.9.5
- web-vitals ^2.1.4
- ws ^8.18.0