Skip to content

Commit a52fe28

Browse files
committed
fix(app): notifications on child sessions
1 parent 8c5ba8a commit a52fe28

1 file changed

Lines changed: 61 additions & 46 deletions

File tree

packages/app/src/context/notification.tsx

Lines changed: 61 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export const { use: useNotification, provider: NotificationProvider } = createSi
6969
}),
7070
)
7171

72-
const meta = { pruned: false }
72+
const meta = { pruned: false, disposed: false }
7373

7474
createEffect(() => {
7575
if (!ready()) return
@@ -84,6 +84,17 @@ export const { use: useNotification, provider: NotificationProvider } = createSi
8484

8585
const index = createMemo(() => buildNotificationIndex(store.list))
8686

87+
const lookup = (directory: string, sessionID?: string) => {
88+
if (!sessionID) return Promise.resolve(undefined)
89+
const [syncStore] = globalSync.child(directory, { bootstrap: false })
90+
const match = Binary.search(syncStore.session, sessionID, (s) => s.id)
91+
if (match.found) return Promise.resolve(syncStore.session[match.index])
92+
return globalSDK.client.session
93+
.get({ directory, sessionID })
94+
.then((x) => x.data)
95+
.catch(() => undefined)
96+
}
97+
8798
const unsub = globalSDK.event.listen((e) => {
8899
const event = e.details
89100
if (event.type !== "session.idle" && event.type !== "session.error") return
@@ -102,61 +113,65 @@ export const { use: useNotification, provider: NotificationProvider } = createSi
102113
switch (event.type) {
103114
case "session.idle": {
104115
const sessionID = event.properties.sessionID
105-
const [syncStore] = globalSync.child(directory, { bootstrap: false })
106-
const match = Binary.search(syncStore.session, sessionID, (s) => s.id)
107-
const session = match.found ? syncStore.session[match.index] : undefined
108-
if (session?.parentID) break
109-
110-
playSound(soundSrc(settings.sounds.agent()))
111-
112-
append({
113-
directory,
114-
time,
115-
viewed: viewed(sessionID),
116-
type: "turn-complete",
117-
session: sessionID,
116+
void lookup(directory, sessionID).then((session) => {
117+
if (meta.disposed) return
118+
if (!session) return
119+
if (session.parentID) return
120+
121+
playSound(soundSrc(settings.sounds.agent()))
122+
123+
append({
124+
directory,
125+
time,
126+
viewed: viewed(sessionID),
127+
type: "turn-complete",
128+
session: sessionID,
129+
})
130+
131+
const href = `/${base64Encode(directory)}/session/${sessionID}`
132+
if (settings.notifications.agent()) {
133+
void platform.notify(
134+
language.t("notification.session.responseReady.title"),
135+
session.title ?? sessionID,
136+
href,
137+
)
138+
}
118139
})
119-
120-
const href = `/${base64Encode(directory)}/session/${sessionID}`
121-
if (settings.notifications.agent()) {
122-
void platform.notify(
123-
language.t("notification.session.responseReady.title"),
124-
session?.title ?? sessionID,
125-
href,
126-
)
127-
}
128140
break
129141
}
130142
case "session.error": {
131143
const sessionID = event.properties.sessionID
132-
const [syncStore] = globalSync.child(directory, { bootstrap: false })
133-
const match = sessionID ? Binary.search(syncStore.session, sessionID, (s) => s.id) : undefined
134-
const session = sessionID && match?.found ? syncStore.session[match.index] : undefined
135-
if (session?.parentID) break
136-
137-
playSound(soundSrc(settings.sounds.errors()))
138-
139-
const error = "error" in event.properties ? event.properties.error : undefined
140-
append({
141-
directory,
142-
time,
143-
viewed: viewed(sessionID),
144-
type: "error",
145-
session: sessionID ?? "global",
146-
error,
144+
void lookup(directory, sessionID).then((session) => {
145+
if (meta.disposed) return
146+
if (session?.parentID) return
147+
148+
playSound(soundSrc(settings.sounds.errors()))
149+
150+
const error = "error" in event.properties ? event.properties.error : undefined
151+
append({
152+
directory,
153+
time,
154+
viewed: viewed(sessionID),
155+
type: "error",
156+
session: sessionID ?? "global",
157+
error,
158+
})
159+
const description =
160+
session?.title ??
161+
(typeof error === "string" ? error : language.t("notification.session.error.fallbackDescription"))
162+
const href = sessionID ? `/${base64Encode(directory)}/session/${sessionID}` : `/${base64Encode(directory)}`
163+
if (settings.notifications.errors()) {
164+
void platform.notify(language.t("notification.session.error.title"), description, href)
165+
}
147166
})
148-
const description =
149-
session?.title ??
150-
(typeof error === "string" ? error : language.t("notification.session.error.fallbackDescription"))
151-
const href = sessionID ? `/${base64Encode(directory)}/session/${sessionID}` : `/${base64Encode(directory)}`
152-
if (settings.notifications.errors()) {
153-
void platform.notify(language.t("notification.session.error.title"), description, href)
154-
}
155167
break
156168
}
157169
}
158170
})
159-
onCleanup(unsub)
171+
onCleanup(() => {
172+
meta.disposed = true
173+
unsub()
174+
})
160175

161176
return {
162177
ready,

0 commit comments

Comments
 (0)