1# hello-realtime
2
3**Hello Realtime** is a OpenAI Realtime app that supports both WebRTC and SIP
4(telephone) users. You can access the app via WebRTC at
5[hello-realtime.val.run](https://hello-realtime.val.run), or via SIP by calling
9server-side websocket interface.
10
11If you remix the app, you'll just need to pop in your own `OPENAI_API_KEY` (from
12[platform.openai.com](https://platform.openai.com)), and if you want SIP, the
13`OPENAI_SIGNING_SECRET`.
14
15## Architecture
18 - Browser connects to frontend
19 - creates WebRTC offer
20 - `/rtc` endpoint handles SDP negotiation with OpenAI
21 - observer established to monitor session
222. **SIP Flow**:
4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1" />
6 <title>OpenAI Realtime API Voice Agent</title>
7 <style>
8 :root {
6const NR_TYPE = "near_field";
7const INSTRUCTIONS = `
8 Greet the user in English, and thank them for trying the new OpenAI Realtime API.
9 Give them a brief summary based on the list below, and then ask if they have any questions.
10 Answer questions using the information below. For questions outside this scope,
23 - higher audio quality
24 - improved handling of alphanumerics (eg, properly understanding credit card and phone numbers)
25 - support for the OpenAI Prompts API
26 - support for MCP-based tools
27 - auto-truncation to reduce context size
9sip.post("/", async (c) => {
10 // Verify the webhook.
11 const OPENAI_SIGNING_SECRET = Deno.env.get("OPENAI_SIGNING_SECRET");
12 if (!OPENAI_SIGNING_SECRET) {
13 console.error("🔴 webhook secret not configured");
14 return c.text("Internal error", 500);
15 }
16 const webhook = new Webhook(OPENAI_SIGNING_SECRET);
17 const bodyStr = await c.req.text();
18 let callId: string | undefined;
1// @ts-ignore
2import { OpenAI } from "https://esm.town/v/std/openai?v=4";
3
4// --- AI BEHAVIORAL GUIDELINES ---
429// --- BACKEND LOGIC ---
430const MAX_DEPTH = 3; // Prevent overly deep recursion and high costs.
431const openai = new OpenAI();
432
433interface Prerequisite {
458
459 try {
460 const completion = await openai.chat.completions.create({
461 model: "gpt-4o",
462 messages: [
1import { createOrUpdateFile } from "./api/create-notes-issues.ts";
2
3import { OpenAI } from "https://esm.sh/openai@5.20.1";
4import { getIssue, readFileContent } from "./api/index.tsx";
5import {
70
71async function getAiSummary(commentBody: string): Promise<string> {
72 const openai = new OpenAI({
73 apiKey: Deno.env.get("OPENAI_API_KEY"),
74 });
75
76 const response = await openai.responses.create({
77 prompt: {
78 "id": "pmpt_68c477e0df8081908a417a427ab285480d8eef1252f514eb",
1import { Hono } from "npm:hono@4.4.12";
2import { z } from "npm:zod@3.23.8";
3import { OpenAI } from "https://esm.town/v/std/openai";
4
5// --- Input and Output Schema Definitions ---
41});
42
43// Defines the comprehensive JSON structure from the OpenAI API.
44const AIResponseSchema = z.object({
45 analysis: z.string(),
245
246 <footer>
247 <p style="text-align:center; font-size: 0.875rem; color: var(--text-secondary)">Powered by <a href="${sourceUrl}" style="color:var(--accent-color-1)">Val Town</a> and OpenAI</p>
248 </footer>
249</div>
540const app = new Hono();
541
542// Middleware to ensure OpenAI client is initialized
543const initMiddleware = (c, next) => {
544 if (!c.get("openai")) {
545 c.set("openai", new OpenAI());
546 }
547 return next();
571
572 const { symptoms, demographics } = validation.data;
573 const openai = c.get("openai");
574
575 try {
576 const completion = await openai.chat.completions.create({
577 model: "gpt-4o",
578 messages: [
639
640 const { topic, message } = validation.data;
641 const openai = c.get("openai");
642
643 const CHAT_SYSTEM_PROMPT = `
653
654 try {
655 const completion = await openai.chat.completions.create({
656 model: "gpt-4o-mini", // Use a faster model for chat
657 messages: [
94Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
95
96### OpenAI
97
98```ts
99import { OpenAI } from "https://esm.town/v/std/openai";
100const openai = new OpenAI();
101const completion = await openai.chat.completions.create({
102 messages: [
103 { role: "user", content: "Say hello in a creative way" },
94Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
95
96### OpenAI
97
98```ts
99import { OpenAI } from "https://esm.town/v/std/openai";
100const openai = new OpenAI();
101const completion = await openai.chat.completions.create({
102 messages: [
103 { role: "user", content: "Say hello in a creative way" },
94Note: When changing a SQLite table's schema, change the table's name (e.g., add _2 or _3) to create a fresh table.
95
96### OpenAI
97
98```ts
99import { OpenAI } from "https://esm.town/v/std/openai";
100const openai = new OpenAI();
101const completion = await openai.chat.completions.create({
102 messages: [
103 { role: "user", content: "Say hello in a creative way" },