Files
openai--openai-agents-python/examples/realtime/app/static/index.html
T
2026-07-13 12:39:17 +08:00

300 lines
7.8 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Realtime Demo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #f8f9fa;
height: 100vh;
display: flex;
flex-direction: column;
}
.header {
background: white;
padding: 1rem;
border-bottom: 1px solid #e1e5e9;
display: flex;
justify-content: space-between;
align-items: center;
}
.connect-btn {
padding: 0.5rem 1rem;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: 500;
transition: background-color 0.2s;
}
.connect-btn.disconnected {
background: #0066cc;
color: white;
}
.connect-btn.connected {
background: #dc3545;
color: white;
}
.connect-btn:hover {
opacity: 0.9;
}
.main {
flex: 1;
display: flex;
gap: 1rem;
padding: 1rem;
height: calc(100vh - 80px);
}
.messages-pane {
flex: 2;
background: white;
border-radius: 8px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.messages-header {
padding: 1rem;
border-bottom: 1px solid #e1e5e9;
font-weight: 600;
}
.messages-content {
flex: 1;
overflow-y: auto;
padding: 1rem;
}
.message {
margin-bottom: 1rem;
display: flex;
}
.message.user {
justify-content: flex-end;
}
.message.assistant {
justify-content: flex-start;
}
.message-bubble {
max-width: 70%;
padding: 0.75rem 1rem;
border-radius: 18px;
word-wrap: break-word;
}
.message.user .message-bubble {
background: #0066cc;
color: white;
}
.message.assistant .message-bubble {
background: #f1f3f4;
color: #333;
}
.right-column {
flex: 1;
display: flex;
flex-direction: column;
gap: 1rem;
}
.events-pane {
flex: 2;
background: white;
border-radius: 8px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.tools-pane {
flex: 1;
background: white;
border-radius: 8px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.events-header, .tools-header {
padding: 1rem;
border-bottom: 1px solid #e1e5e9;
font-weight: 600;
}
.events-content, .tools-content {
flex: 1;
overflow-y: auto;
padding: 0.5rem;
}
.event {
border: 1px solid #e1e5e9;
border-radius: 6px;
margin-bottom: 0.5rem;
}
.event-header {
padding: 0.75rem;
background: #f8f9fa;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
font-family: monospace;
font-size: 0.85rem;
}
.event-header:hover {
background: #e9ecef;
}
.tools-content .event-header {
cursor: default;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.tools-content .event-header.handoff {
background: #f3e8ff;
border-left: 4px solid #8b5cf6;
}
.tools-content .event-header.tool {
background: #fef3e2;
border-left: 4px solid #f59e0b;
}
.event-content {
padding: 0.75rem;
background: white;
border-top: 1px solid #e1e5e9;
font-family: monospace;
font-size: 0.8rem;
white-space: pre-wrap;
max-height: 200px;
overflow-y: auto;
}
.event-content.collapsed {
display: none;
}
.controls {
padding: 1rem;
border-top: 1px solid #e1e5e9;
background: #f8f9fa;
display: flex;
gap: 0.5rem;
align-items: center;
}
.mute-btn {
padding: 0.5rem 1rem;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: 500;
transition: all 0.2s;
}
.mute-btn.unmuted {
background: #28a745;
color: white;
}
.mute-btn.muted {
background: #dc3545;
color: white;
}
.mute-btn.active {
animation: pulse 1s infinite;
}
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.7; }
100% { opacity: 1; }
}
.status {
font-size: 0.9rem;
color: #6c757d;
}
.connected {
color: #28a745;
}
.disconnected {
color: #dc3545;
}
</style>
</head>
<body>
<div class="header">
<h1>Realtime Demo</h1>
<button id="connectBtn" class="connect-btn disconnected">Connect</button>
</div>
<div class="main">
<div class="messages-pane">
<div class="messages-header">
Conversation
</div>
<div id="messagesContent" class="messages-content">
<!-- Messages will appear here -->
</div>
<div class="controls">
<button id="muteBtn" class="mute-btn unmuted" disabled>🎤 Mic On</button>
<input id="imagePrompt" type="text" placeholder="Optional prompt for image" style="flex: 1; padding: 0.5rem; border: 1px solid #e1e5e9; border-radius: 6px;" />
<input id="imageInput" type="file" accept="image/*" aria-hidden="true" style="position:absolute;left:-9999px;width:1px;height:1px;opacity:0;" />
<button id="imageBtn" type="button" class="mute-btn unmuted" style="background:#6f42c1; user-select:none;">🖼️ Send Image</button>
<span id="status" class="status disconnected">Disconnected</span>
</div>
</div>
<div class="right-column">
<div class="events-pane">
<div class="events-header">
Event stream
</div>
<div id="eventsContent" class="events-content">
<!-- Events will appear here -->
</div>
</div>
<div class="tools-pane">
<div class="tools-header">
Tools & Handoffs
</div>
<div id="toolsContent" class="tools-content">
<!-- Tools and handoffs will appear here -->
</div>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>