{"id":26201830,"url":"https://github.com/danielstern/tau.js","last_synced_at":"2025-09-05T23:51:44.154Z","repository":{"id":277816655,"uuid":"931116883","full_name":"danielstern/tau.js","owner":"danielstern","description":"Node.js Library for Making Realtime OpenAI Communication Easy and Fast","archived":false,"fork":false,"pushed_at":"2025-03-04T13:15:38.000Z","size":154,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-06T06:34:18.908Z","etag":null,"topics":["4o","gpt-4","nodejs","realtime","websockets"],"latest_commit_sha":null,"homepage":"https://github.com/danielstern/tau.js","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danielstern.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-11T18:38:58.000Z","updated_at":"2025-03-20T01:20:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"40b852aa-747c-4e43-b5a2-446ba8b2b896","html_url":"https://github.com/danielstern/tau.js","commit_stats":null,"previous_names":["danielstern/tau.js"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielstern%2Ftau.js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielstern%2Ftau.js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielstern%2Ftau.js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielstern%2Ftau.js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielstern","download_url":"https://codeload.github.com/danielstern/tau.js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249016625,"owners_count":21198832,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["4o","gpt-4","nodejs","realtime","websockets"],"created_at":"2025-03-12T03:23:54.090Z","updated_at":"2025-09-05T23:51:44.141Z","avatar_url":"https://github.com/danielstern.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv\u003e\n\u003cpicture\u003e\n\u003cimg style=\"margin-bottom:12px\" src=\"https://storage.googleapis.com/owned-io-public-files/images/tau-logo.png\"\u003e\n\u003c/picture\u003e\n\u003c/div\u003e\n\u003cdiv style=\"display:flex; gap: 16px\"\u003e\n\u003c!-- \u003ca href=\"https://github.com/danielstern/tau.js/blob/master/LICENSE\" target=\"_blank\"\u003e\n\u003c/a\u003e --\u003e\n\u003cpicture\u003e\n\u003cimg src=\"https://img.shields.io/badge/License-MIT-steelblue\"\u003e\n\u003c/picture\u003e\n\u003cpicture\u003e\n\u003cimg src=\"https://img.shields.io/badge/version-alpha-orange\"\u003e\n\n\u003c/picture\u003e\n\u003cpicture\u003e\n\u003cimg src=\"https://img.shields.io/badge/node-18.20.4-darkgreen\"\u003e\n\u003c/picture\u003e\n\u003ca href=\"https://www.npmjs.com/org/tau-js\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/npm-@tau--js-purple\"\u003e\n\u003c/a\u003e\n\n\u003c/div\u003e\n\u003cdiv style=\"margin-bottom:20px\"\u003e\u003c/div\u003e\n\n# tau.js \u003cimg width=20px src=\"https://favicon-generator-1041699091324.us-central1.run.app/icon\"\u003e \n*The Easy and Intuitive Way to Work with Realtime AI Voice Models!*\n### What is `tau.js`\n`tau.js` is a node library that greatly simplifies the Websocket API used to communicate with realtime AI models like `4o-realtime`, and adds essential features like realtime voice debugging.\n\nWith `tau.js`, Starting a session and generating a voice response is as simple as:\n\n```javascript\nimport { create_session } from \"@tau/core\"\n\nlet session = await create_session()\nawait session.system(\"Whenever prompted to respond, state a different teaching of the Sun Tzu.\")\nawait session.response()\n\n// \"The supreme art of war is to subdue the enemy without fighting.\"\n```\n## Why Use `tau.js`?\n`tau.js` greatly reduces ramp-up time when building applications with OpenAI's `4o-realtime` and `4o-mini-realtime` models. \n### Simple Async/Await Interface\nRealtime AI sessions are based on Websockets. This is very good, as websockets are extremely fast and they're a critical part of delivering a fast user experience. But Websockets are hard to develop for and tend to create messy code that can't be maintained.\n\n`tau.js` solves this problem by black-boxing away all websocket logic and instead providing a dead-simple `async/await` API with which to build powerful realtime apps.\n\n\n### Cost Estimation\nTau computes total usage costs for sessions by using usage data returned from responses combined with publicly available pricing data for supported APIs. Tau cost computation turns opaque token counts into one salient cost number which assists in managing development costs and planning deployment costs.\n\n\n```javascript\n// example usage data\n{\n    computed: { total_usage_cost: 0.07504 },\n    tokens: {\n        realtime_input_text_tokens: { tokens: 520, cpm: 5, usage_cost: 0.0026 },,\n        realtime_output_audio_tokens: { tokens: 458, cpm: 80, usage_cost: 0.03664 }\n  }\n}\n```\n\n**Computed usage cost is an estimate** and is likely to differ somewhat from actual usage costs incurred.\n\n### Sophisticated Debug Server\nOne of the most difficult parts of getting started with realtime audio is handling and processing PCM audio data. \n`tau.js` includes a UI where you can...\n- **Listen to incoming audio in real time**\n- **Input voice and get responses in realtime**\n- Review usage data\n\n\u003ca href=\"https://owned.io/tau/debugger/\" target=\"_blank\"\u003e\n\u003cimg  src=\"https://storage.googleapis.com/owned-io-public-files/images/2025-02-12%2006_51_21-tau.js%20debugger.png\"\u003e\n\u003c/a\u003e\n\n### Session Recovery\nSessions with AI models are nondeterministic, and sometimes they close unexpectedly. This is a big problem, because sometimes the state of your session with the model is closely tied to your application experience or other dependent models.\n`tau.js` solves this by adding customizable, sophisticated session recovery. When the socket closes unexpectedly, if recovery is enabled, tau will attempt to recreate a session as similar to the original as possible by replaying previous messages.\n\n## Quick Start Guide\nDeveloping with Realtime AI Models is simple and easy with `tau.js`. You can be conversing with your model in short order by following these steps:\n1. Install `tau.js`\n```sh\nnpm install --save @tau-js/core\n```\n\n2. Start the `debug` server\n```\nnpm install -g @tau-js/cli\ntau debug start\n```\n\n3. Create a session and start working in realtime with AI!\n```javascript\nimport { create_session } from \"@tau-js/core\"\n\nlet session = await create_session({\n    instructions : \"You're a wise, worldly assistant who is always looking out for the user.\",\n    modalities : [\"text\",\"audio\"]\n    temperature : 0.69,\n    voice: \"verse\"\n}, {\n    model : \"4o\",\n    debug: true,\n    api_key : \"sk-1234-abcd\"\n})\n\nawait session.system(\"Speak in a tough, brassy, raspy, confident, assured, deep Scottish brogue.\")\nawait session.user(\"Why did Napoleon lose the battle of Waterloo?\")\nawait session.response({\n    conversation : \"none\",\n})\n```\n\n```sh\n# If provided, the OPENAI_API_KEY environment variable will be used as the API key for all sessions.\nOPENAI_API_KEY=sk-1234567890abcdefg\n```\n\n## Understanding and Using the Debug Server + UI\n\nThe most challenging part of getting up-and-running when working with real-time voice models is handling voice input and decoding and playing voice output.\n\nThe Debug Server + UI makes this usually difficult process simple and easy:\n\n```sh\nnpm install -g @tau-js/cli\ntau debug start\n```\n\nThis will start a local debug server, as well as open the debug UI at \u003ca href=\"https://owned.io/tau/debugger/\"\u003ehttps://owned.io/tau/debugger\u003c/a\u003e.  \n\nIn order to enable audio playback and microphone access, you need to click on the debugger UI. \n\nThe debug UI is still in development. You'll be able to run the debug UI locally, if desired, as part of future releases. You can still use `tau.js` without the debugger if you want an entirely localized experience.\n\nEnable debug output from a tau session by passing `{ debug : true }` (see examples) or by setting the following environment variable:\n\n```sh\n# If enabled, sessions will automatically connect to debug server\nTAU_DEBUG=true\n```\n\n\n\n## Examples\n### Example: Creating a Simple Realtime Translator\nThe example below is very simple but creates an effective and very fast universal translator. You can even specify how you want your translator to speak. \nIf you provide voice input to a translator like this, it will match the user's emphasis and tone of voice.\n```javascript\nimport { create_session } from \"@tau-js/core\"\nlet session = await create_session({\n    instructions : \"You are translation assistant. Translate all user input.\",\n    modalities : [\"text\", \"audio\"],\n    voice : \"ash\",\n},{\n    debug : true,\n})\n\nawait session.system(\"Translate user input into German. Speak in a friendly voice, loudly and clearly annunciating.\")\nawait session.user(\"Excuse me, is this where I catch the train to the airport?\")\nawait session.response()\n// Entschuldigen Sie, ist das hier der Ort, wo ich den Zug zum Flughafen nehmen kann?\n```\n\n### Example: Creating a Dramatic Vocaloid\nRealtime voice models (vocaloids) can produce surprisingly powerful and emotionally compelling audio. \n\nThis example also showcases using a utility to save the audio is `wav` for later use.\n\n```javascript\nimport { create_session } from \"@tau-js/core\"\nimport { audio_finished, save_deltas_as_wav } from \"@tau-js/utility\"\n\nlet session = await create_session({\n    modalities : [\"text\", \"audio\"],\n    instructions: \"You are a dramatic acting vocaloid.\",\n    voice: \"ash\"\n}, {\n    model : \"4o\",\n    debug: true\n})\n\nawait session.system(\"Repeat after the user.\")\nawait session.system(\"Speak in a deep, raspy, brassy, assured Scottish brogue.\")\nfor (let line of [\n    \"**SOFTLY, ARROGANTLY** I've seen things you people wouldn't believe. **DISMISSIVELY** Hmph.\",\n    \"**EXCITED, FRIENDLY** Attack ships on fire off th'shoulder of Orion!\",\n    \"**SADLY** I watched C-beams... glitter in the dark near the Tannhäuser Gate!\",\n    \"**SADLY, CRYING, NOSTALGIC, WITH DRAMATIC TIMING** All those... moments will be lost... in time, like **CLEARS THROAT** tears... in rain.\",\n    \"**CALMLY, ACCEPTING** Time... to die.\"\n]) {\n    await session.user(line)\n    let response = await session.response()\n    await audio_finished(response)\n    save_deltas_as_wav(response.audio_deltas)\n}\n\nconsole.info(session.usage)\nsession.close()\n```\n[Listen to the output 🔊🤯](https://storage.googleapis.com/owned-io-public-files/images/voice-1739534240862.wav)\n\u003c!-- \u003caudio controls src=\"https://storage.googleapis.com/owned-io-public-files/images/voice-1739533651706.wav\"\u003e\u003c/audio\u003e --\u003e\n\n### Example: Language Tutor\nThis tutor will patiently work with any student to learn any target phrase in any known language. \n\nThe tutor is able to listen to the user's pronunciation and provide customized and very helpful feedback.\n\n\n\n```javascript\nimport { create_session } from \"@tau-js/core\"\n\nlet target_language = \"Japanese\"\nlet target_phrase = \"Two is enough, really!\"\n\nlet tutor = await create_session({\n    instructions : `You're a friendly, helpful language tutor who is helping the user learn the ${target_language} language. Assume they have no previous knowledge of the target language. Speak all instructions in English. Your task is to help the user improve their pronunciation of the target phrase.`,\n    modalities : [\"text\",\"audio\"],\n    temperature : 0.69,\n    voice: \"ash\",\n    turn_detection : {\n        type : \"server_vad\",\n        silence_duration_ms : 800\n    }\n    \n}, {\n    model : \"4o-mini\",\n    debug: true\n})\n\nawait tutor.system(`The target phrase is: '${target_phrase}'. The target language is ${target_language}`)\nawait tutor.system(\"Speak the target phrase in English. Then translate the target phrase into the target language and repeat it once. Finally, ask the user to speak the phrase 2-3 times.\")\n\nawait tutor.response()\nawait tutor.system(`\n    The user will now speak the target phrase. If the user's input is not clear enough to interpret, ask them to repeat themselves more clearly.\n\n    Identify **one** area of the user's pronunciation to improve upon (don't overwhelm the user with multiple pieces of feedback at once), instruct the user on how to improve, and ask them to repeat the target phrase again. Always end your response by repeating the target phrase.\n\n    Then, identify a **different** area of pronunciation to improve upon. and repeat the above process.\n\n    Never conclude the conversation or change the target phrase. The goal is refine the target phrase to perfection and beyond.\n`)\n\n// Your pronunciation is quite good! Let's focus on the pitch accent for the word 「十分」 (jūbun). Make sure to emphasize the first syllable, \"jū,\" and keep the second syllable, \"bun,\" softer. This way, the word flows naturally and clearly. Please try saying the phrase again: 「二つで十分だよ！」🍜🍜🍜\n```\n\n### Example: Function-calling Assistant\nThis interesting example implements a real-time assistant which helps the user with simple tasks around the home.\n- The `silence_duration_ms` parameter dictates how long the model waits before responding. If this value is too high, then the model seems slow and unresponsive. But if it's too low, the model will cut in and interrupt the user, which is even worse. However, when combined with non-vocalizing, function-calling models, a short time works very well. \n- **Combining voice output with function calling in a single model works inconsistently, at best**. Vocaloids (voice-producing models) tend to get \"in\" to their roles after a few responses. Calling functions confuses them and results in suboptimal output for both voice and function calls. It's better to use multiple sessions, as in the below example.\n\n```javascript\nimport { create_session } from \"@tau-js/core\"\n\nlet name = `Rachel`\n\nlet assistant = await create_session({\n    instructions : `You're an automated function calling unit designed to assist the user in household activities. Your name is ${name}.`,\n    modalities : [\"text\"],\n    temperature : 0.65,\n    turn_detection : {\n        type : \"server_vad\",\n        silence_duration_ms : 200\n    },\n    tools : [\n        {\n            name : \"pass\",\n            type : \"function\",\n            description : \"Call this method by default when you fail to detect BOTH your name and the command in the user's input.\"\n        },\n        {\n            name : \"turn_lights_on\",\n            type : \"function\",\n            description : \"Call this method when the user asks you to turn the lights on.\"\n        },\n        {\n            name : \"turn_lights_off\",\n            type : \"function\",\n            description : \"Call this method when the user asks you to turn the lights off.\"\n        },\n        {\n            name : \"you_are_welcome\",\n            type : \"function\",\n            description : \"Call this method to acknowledge when the user thanks you.\"\n        },\n    ],\n    tool_choice : \"required\"\n   \n}, {\n    model : \"4o\",\n    debug: true\n})\n\nawait assistant.system(`Listen to the user's speech. The user may issue a command at any given time. If the user speaks your name in full, then speaks a command compatabile with an available function, call that function.`)\n\nlet assistant_vocaloid = await create_session({\n    instructions : \"You are the voice output model for another model.\",\n    modalities : [\"text\",\"audio\"],\n    voice : \"shimmer\"\n},{\n    model : \"4o\",\n    debug : true,\n    debug_voice_in : false\n})\n\nawait assistant_vocaloid.system(\"Speak in a friedly, confident, refined british accent.\")\n\nassistant.response$.subscribe(async data =\u003e {\n    let name = data.function_call.name\n\n    if (name === \"you_are_welcome\") {\n        await assistant_vocaloid.system(\"Please say, 'You're most welcome!'\")\n        await assistant_vocaloid.response()\n    }\n})\n\n// \"I'm kinda tired.\"\n// \u003e pass\n// \"Rachel, can you turn the lights off please?\"\n// \u003e turns_lights_off (in under 900ms)\n// \"Thank you, Rachel.\"\n// \u003e \"You are most welcome!\" 🤯🤯🤯\n```\n### Example: Ensemble Performance\nIn the following multi-vocaloid example, three different vocaloids perform a scene with their own unique accents.\nThe output of each vocaloid is passed to the others, giving the models the ability to \"play off\" each other and create interesting, engaging and entertaining **live** performances.\nOther than creating the vocaloids, which should be done in sequence to prevent 429 errors, all inter-vocaloid communication can be handled in parallel, meaning that a program like this can scale to any number of players with no performance decrease.\n```javascript\nimport { create_session } from \"@tau-js/core\";\nimport { audio_finished } from \"@tau-js/utility\"\n\nlet instructions = \"You are a comedic vocalizer unit. Read your line exactly as provided.\"\n\n/**\n * Note that while it is tempting to create all the session in parallel, this can result in a 429 too many requests, so it's more consistent to create them one at a time. \n */\nlet players = {\n    brian : await create_session({voice : \"ash\",instructions}),\n    passerby : await create_session({voice : \"verse\",instructions}),\n    marketgoer : await create_session({voice : \"ballad\",instructions})\n}\n\nawait players['brian'].system(\"Speak in in an hilarious, nervous sophisticated Liverpool accent.\")\nawait players['passerby'].system(\"Speak in an hilarious cockney London accent.\")\nawait players['marketgoer'].system(\"Whisper in an hilarous, maniacal Scottish brogue.\")\n\nlet dialog = [\n    [\n        \"brian\",\n        \"Don't pass judgement on... other people or... **CLEARS THROAT** you may get judged yourself!\",\n        \"**NERVOUSLY, IMPROVISING, PONTIFICATING**\",\n    ],\n    [\n        \"passerby\", \n        \"What?!\",\n        \"**DISBELIEVING**\", \n    ],\n    [\n        \"brian\",\n        \"I said don't pass judgement on other people or *you* might get judged *too*.\",\n        \"**HOPEFULLY, CHEERFULLY**\", \n    ],\n    [\n        \"passerby\", \n        \"Who, me?\",\n        \"**HAPPILY**\", \n    ],\n    [\n        \"brian\",\n        \"Yes!\"\n    ],\n    [\n        \"passerby\", \n        \"Oh, thanks very much!\",\n        \"**GIDDILY**\", \n    ],\n    [\n        \"brian\", \n        \"**Well, not just you. *All* of you!**\", \n    ],\n    [\n        \"marketgoer\",\n        \"... that's a nice gourd.\",\n        \"**CONSPIRATORILY, TIPSILY**\"\n    ]\n]\n\nfor (let [player_name, line, direction] of dialog) {\n    let player = players[player_name]\n    let input = `LINE: \"${line}\"`\n    if (direction) input = `Speak as follows: ${direction}. ${input}`\n    await player.user(input)\n    let response = await player.response()\n    let deltas = response.audio_deltas\n    \n    /**\n     * The audio deltas are ready long before the audio itself has finished playing, so it's possible for the other players to begin processing before the previous line has finished.\n     * Since calling `create_audio` doesn't make any HTTP requests, it won't 429 and it's possible to do any number in parallel.\n     * */\n    await Promise.all([\n        ... Object.keys(players)\n            .filter(key =\u003e key !== player_name)\n            .map(key =\u003e players[key])\n            .map(player =\u003e player.create_audio(deltas.join(\"\"))),\n        /**\n         * The `audio_finished` utility returns a promise that resolves \n         * around when the audio associated with a given response would \n         * stop playing, if it started playing as early as possible.\n         */\n        audio_finished(response)\n    ])\n}\n\nfor (let player_name in players) {\n    players[player_name].close()\n}\n```\n\n\n# API Reference\n# `create_session`\n\nCreates a new real-time model session by opening a persistent websocket connection to the model endpoint. This function is equivalent to opening a websocket connection and then calling `session.update` with the same options.\n\n## Signature\n\n```typescript\nasync function create_session(\n  session_options: { ... },\n  tau_options: { ... }\n): Promise\u003cSession\u003e\n```\n\n## Parameters\n\n### `session_options`\n\n- **`voice?`** (`Voice`):  \n  Voice identifier for audio output. Leave undefined to use the default.  \n  *Note: Cannot be changed after session initialization.*\n    \n    Available Voices:\n    - **alloy**\n    - **ash**\n    - **ballad**\n    - **coral**\n    - **echo**\n    - **shimmer**\n    - **sage**\n    - **verse**\n\n- **`instructions?`** (`Instructions`):  \n  Default instructions for the model (works like system prompts).  \n  Use an empty string for no instructions or undefined for default instructions.\n\n- **`temperature?`** (`Temperature`):  \n  A number between 0.6 and 1.2. Higher values yield more random outputs; lower values yield more deterministic responses and may improve performance.\n\n- **`tool_choice?`** (`ToolChoice`):  \n  Guidance on whether the model should use a tool when generating a response.  \n  - `\"auto\"` (default): Model chooses.  \n  - `\"required\"`: Model should use a tool.  \n  - `\"none\"`: Model should not use a tool.  \n  - `{ type: \"function\", name: string }`: Specifies a particular function tool.\n\n- **`tools?`** (`Tool[]`):  \n  An array of available tools (functions) for the model.\n\n- **`turn_detection?`** (`TurnDetection`):  \n  Enables automatic handling of voice input via turn detection. When enabled, the server monitors the audio buffer and commits it after a defined period of silence.\n\n- **`modalities?`** (`Modalities`):  \n  Determines the output format. Acceptable values: `[\"text\"]` or `[\"text\", \"audio\"]`.  \n  *Note: Only text or text with audio is supported.*\n\n### `tau_options`\n\n- **`api_key?`** (`ApiKey`):  \n  API key for the session. If undefined, the `OPENAI_API_KEY` environment variable is used.\n\n- **`model?`** (`Model`):  \n  The model to use. Defaults to `gpt-4o-realtime`.\n\n- **`version?`** (`Version`):  \n  The model to use. Defaults to `VERSIONS[\"latest\"]`.\n\n- **`name?`** (`Name`):  \n  Optional session identifier for debugging purposes.\n\n- **`ws_url`**\n  \n\n## Returns\n\nA `Promise` that resolves to a `Session` object, which provides methods to interact with the conversation, manage audio input, generate responses, and handle debugging events.\n\n# Session Interface\n\nThe `Session` interface provides methods and properties for interacting with a real-time AI model session. Use it to manage conversation items, handle audio input, generate responses, and access debugging tools.\n\n## Methods\n\n### `user(message: string): Promise\u003cConversationItem\u003e`\nCreates a new conversation item with the role `user` using the provided text.\n\n### `assistant(message: string): Promise\u003cConversationItem\u003e`\nCreates a new conversation item with the role `assistant` using the provided text.\n\n### `system(message: string): Promise\u003cConversationItem\u003e`\nCreates a new conversation item with the role `system` (developer/system message) using the provided text.\n\n### `create_audio(bytes: string): Promise\u003cConversationItem\u003e`\nCreates a new conversation item with the role `user` using the provided audio bytes as content.\n\n### `append_input_audio_buffer(bytes: string): Promise\u003cvoid\u003e`\nAppends audio bytes to the input buffer. Unlike `create_audio`, this does not immediately create a conversation item; the buffer is committed later, either manually or automatically via turn detection.\n\n### `commit_input_audio_buffer(): Promise\u003cvoid\u003e`\nCommits the audio in the input buffer, creating a conversation item. When turn detection is enabled, this is handled automatically.\n\n### `cancel_response(): Promise\u003cvoid\u003e`\nCancels an in-progress response generation.\n\n### `delete_conversation_item(item_id): Promise\u003cvoid\u003e`\nDeletes a conversation item from the default conversation. The `item_id` is obtained from a previously created conversation item.\n\n### `response(response_options?: ResponseOptions): Promise\u003cResponse\u003e`\nGenerates a new assistant message and adds it to the conversation.  \n*Note:* The default conversation supports only one active response at a time, unless set to \"none\".\n\n### `close(): void`\nEnds the session and closes all associated websocket connections.\n\n## Properties\n\n- **`name: string`**  \n  The session's name (useful for debugging).\n\n- **`session: SessionDetails`**  \n  Detailed information about the current session.\n\n- **`usage: UsageData`**  \n  Accumulated token usage and cost for the session.\n\n- **`ws: WebSocket`**  \n  The active websocket connection for low-level debugging and custom implementations.\n\n- **`event$: Observable\u003cany\u003e`**  \n  An observable that emits data received from the remote server.  \n  *Usage:* `event$.subscribe(handler)`\n\n- **`response$: Observable\u003cResponse\u003e`**  \n  An observable that fires whenever the server generates a response. The data includes pre-processed usage information.  \n  *Usage:* `response$.subscribe(handler)`\n\n\n# ResponseOptions Interface\n\nDefines options to customize the generation of a model response.\n\n## Properties\n\n- **`conversation?`** (`Conversation`):  \n  Specifies which conversation to add the response to.  \n  - `\"auto\"`: Adds the response to the default conversation, influencing future outputs.  \n  - `\"none\"`: The response is not added to any conversation; it is transient and does not affect future outputs.\n\n- **`tools?`** (`Tool[]`):  \n  An array of tools (e.g., functions) available for use during response generation.  \n  *Note:* Does not override previously supplied tools; it makes the model more inclined to use the specified ones.\n\n- **`tool_choice?`** (`ToolChoice`):  \n  Guidance on which tool to use when generating the response.  \n  Options include: `\"auto\"`, `\"required\"`, `\"none\"`, or a specific function tool defined as `{ type: \"function\", name: string }`.\n\n- **`temperature?`** (`Temperature`):  \n  A numeric value between 0.6 and 1.2. Higher values yield more random output.\n\n- **`instructions?`** (`Instructions`):  \n  Provides guidance on how to generate the response, functioning similarly to a system message.  \n  If omitted, the session’s default instructions or the model's built-in defaults are used.\n\n- **`input?`** (`ConversationItem[]`):  \n  An array of conversation items to use as context for the response.  \n  Specifying this ignores the default conversation history.\n\n- **`metadata?`** (`Metadata`):  \n  Custom metadata attached to the response request.\n\n # Tool Interface\n\nDefines a tool available for the model, typically representing a callable function.\n\n## Properties\n\n- **`name: string`**  \n  The name of the function or tool.\n\n- **`type: \"function\"`**  \n  Specifies the tool type. Currently, only `\"function\"` is supported.\n\n- **`description: string`**  \n  A description of what the tool does.\n\n- **`parameters`** (`object`):  \n  Describes the input accepted by the tool.\n  \n  - **`type: \"object\"`**  \n    Indicates that the tool accepts an object as input.\n  \n  - **`properties: { [key: string]: { type: \"string\" | \"number\", description: string, examples: string[] } }`**  \n    An object mapping parameter names to their definitions, where each parameter includes:\n    - **`type`**: The expected data type (e.g., `\"string\"` or `\"number\"`).\n    - **`description`**: A description of the parameter.\n    - **`examples`**: Example values for the parameter.\n  \n  - **`required: string[]`**  \n    An array of parameter names that must be included in every call to this tool. \n\n\n## Environment Variables\n```sh\n# If provided, will be used as the API key for all sessions.\nOPENAI_API_KEY=sk-1234567890abcdefg\n# If enabled, sessions will automatically connect to debug server. \nTAU_DEBUG=true\n# If 0, no non-error logs will be output to console. If 1 some logs will be published. If 2 or more, full logs will be published.\nTAU_LOGGING=2\n```\n\n## FAQ\n### What ML models does `tau.js` support?\nTau currently supports OpenAI's `4o-realtime` and `4o-mini-realtime` models. \n\n### Can I contribute to `tau.js`?\nIf you have an idea, suggestion, bug fix request or question, create an issue or pull request. If presenting a bug, be sure to provide enough information to consistently reproduce that bug. \n\n### How do I contact the developers and maintainers of `tau.js`?\nLead Developer / Lead Maintainer / Code Whisperer - Daniel J. Stern (daniel@herald.to)\n\n### Will `tau.js` support non-realtime models like `o1` or `4o`?\nNo, `tau.js` is focused entirely on supporting realtime, websocket based models. \n\n### Will `tau.js` support realtime models other than `OpenAI` models?\nYes, `tau.js` will support competing realtime models as they come along. Please direct suggestions to the `issues` page.\n\n### Is `tau.js` actively maintained?\nYes. `tau.js` is maintained actively and will continue to update to support additional models and features of those models.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielstern%2Ftau.js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielstern%2Ftau.js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielstern%2Ftau.js/lists"}