Skip to content

Commit fc41b39

Browse files
committed
feat: shows the hydrated conversation from the client in WebRTC SDK
1 parent ae632cb commit fc41b39

File tree

3 files changed

+39
-22
lines changed

3 files changed

+39
-22
lines changed

apps/browser-example/src/components/ConversationView.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,12 @@ import type {
44
RealtimeConversationItem,
55
RealtimeConversationItemContent,
66
} from "@tsorta/browser/openai"
7-
import {
8-
DefinedRole,
9-
RealtimeConversationItemSimple,
10-
simplifyItem,
11-
} from "./simpleConversation"
7+
import { DefinedRole, simplifyItem } from "./simpleConversation"
128

139
const log = console
1410

1511
export interface ConversationProps {
16-
conversation: RealtimeConversationItemSimple[]
12+
conversation: RealtimeConversationItem[]
1713
}
1814

1915
export const ConversationView = ({
@@ -93,7 +89,8 @@ const ConversationItem = ({
9389

9490
<div
9591
key={id}
96-
className={`mb-5 p-3 rounded-pill ${RoleBgColorMap[role]} ${RoleTextColorMap[role]}`}
92+
className={`mb-5 ${RoleBgColorMap[role]} ${RoleTextColorMap[role]}`}
93+
style={{ padding: "1.5rem 1.5rem", borderRadius: "5rem" }}
9794
>
9895
<div className="my-content">
9996
{content.map((contentItem, index) => (

apps/browser-example/src/components/RealtimeSessionView.tsx

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import { ReactNode, useState } from "react"
22
import { BootstrapIcon } from "./BootstrapIcon"
33
import { EventList } from "./EventList"
44
import { useModal } from "../hooks/useModal"
5-
import { RealtimeSessionCreateRequest } from "@tsorta/browser/openai"
5+
import {
6+
RealtimeConversationItem,
7+
RealtimeSessionCreateRequest,
8+
} from "@tsorta/browser/openai"
69
import { ConversationView } from "./ConversationView"
710

811
type PartialSessionRequestWithModel = Partial<RealtimeSessionCreateRequest> &
@@ -16,13 +19,15 @@ interface RealtimeSessionViewProps {
1619
stopSession: () => Promise<void>
1720
sessionStatus: "unavailable" | "stopped" | "recording"
1821
events: { type: string }[]
22+
conversation?: RealtimeConversationItem[]
1923
}
2024

2125
export function RealtimeSessionView({
2226
startSession,
2327
stopSession,
2428
sessionStatus,
2529
events,
30+
conversation,
2631
}: RealtimeSessionViewProps): ReactNode {
2732
// TODO: allow user to select the model
2833
const model = "gpt-4o-realtime-preview-2024-12-17"
@@ -31,6 +36,10 @@ export function RealtimeSessionView({
3136
undefined
3237
)
3338

39+
const [activeTab, setActiveTab] = useState<"events" | "conversation">(
40+
"events"
41+
)
42+
3443
const modal = useModal({
3544
title: "Edit Instructions",
3645
children: (
@@ -132,56 +141,66 @@ export function RealtimeSessionView({
132141
</li>
133142
</ul>
134143

135-
<ul className="nav nav-tabs mb-3" role="tablist">
144+
<ul className="nav nav-tabs mt-3" role="tablist">
136145
<li className="nav-item" role="presentation">
137146
<button
138-
className="nav-link active"
147+
className={`nav-link ${activeTab === "events" ? "active" : ""}`}
139148
id="events-tab"
140-
data-bs-toggle="tab"
141-
data-bs-target="#events"
142149
type="button"
143150
role="tab"
144151
aria-controls="events"
145-
aria-selected="true"
152+
aria-selected={activeTab === "conversation"}
153+
onClick={() => setActiveTab("events")}
146154
>
147155
Events
148156
</button>
149157
</li>
150158
<li className="nav-item" role="presentation">
151159
<button
152-
className="nav-link"
160+
className={`nav-link ${
161+
activeTab === "conversation" ? "active" : ""
162+
}`}
153163
id="conversation-tab"
154-
data-bs-toggle="tab"
155-
data-bs-target="#conversation"
156164
type="button"
157165
role="tab"
158166
aria-controls="conversation"
159-
aria-selected="false"
167+
aria-selected={activeTab === "conversation"}
168+
onClick={() => setActiveTab("conversation")}
160169
>
161170
Conversation
162171
</button>
163172
</li>
164173
</ul>
165174
<div className="tab-content">
166175
<div
167-
className="tab-pane fade show active"
176+
className={`tab-events tab-pane fade ${
177+
activeTab === "events" ? "show active" : ""
178+
}`}
168179
id="events"
169180
role="tabpanel"
170181
aria-labelledby="events-tab"
171182
>
172183
<EventList events={events} />
173184
</div>
174185
<div
175-
className="tab-pane fade"
186+
className={`tab-events tab-pane fade ${
187+
activeTab === "conversation" ? "show active" : ""
188+
}`}
176189
id="conversation"
177190
role="tabpanel"
178191
aria-labelledby="conversation-tab"
179192
>
180-
<div>TODO</div>
181-
{/*<ConversationView conversation={} />*/}
193+
{conversation && conversation.length > 0 ? (
194+
<ConversationView conversation={conversation} />
195+
) : (
196+
<div className="alert alert-info m-2" role="alert">
197+
{conversation !== undefined
198+
? "Conversation data not yet available. Start a session and talk and they should appear."
199+
: "Conversations not available in this SDK"}
200+
</div>
201+
)}
182202
</div>
183203
</div>
184-
<EventList events={events} />
185204
</div>
186205
)
187206
}

apps/browser-example/src/pages/WebRTCExample.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export function WebRTCExample({
9494
stopSession={stopSession}
9595
sessionStatus={sessionStatus}
9696
events={events}
97+
conversation={conversation}
9798
/>
9899
</div>
99100
)

0 commit comments

Comments
 (0)