Skip to content

Commit fe57bc5

Browse files
committed
fix(webapp,sdk): address PR review nits
Four follow-up nits from the second-pass review on #3542. .server-changes/sessions-dashboard-and-task-source-filter.md — adds the missing high-level entry for the webapp surface (Sessions page + task-source filter on Runs). The two existing changesets only cover @trigger.dev/sdk and @trigger.dev/core, so the dashboard work wouldn't have shown up in a future server changelog. apps/webapp/app/routes/realtime.v1.sessions.$session.$io.records.ts — switched `const loader = ...; export { loader }` to `export const loader = ...` to match the sibling `api.v1.deployments.current.ts` and the rest of the route file convention. Functionally identical. packages/core/src/v3/sessionStreams/manager.ts + packages/core/src/v3/inputStreams/manager.ts — two clarifications: (1) added a JSDoc to `disconnect()` documenting that it intentionally leaves handlers and waiters in place, so any registered listener will trigger an auto-reconnect with backoff. Distinguishes from `reset()` (full clean state, rejects waiters) and `disconnectStream` (single key, stays down until fresh `on()`/`once()`). (2) `disconnectStream` now clears `reconnectAttempts` for the key — an explicit teardown is not evidence of a broken backend, and a future re-attach should start the backoff at attempt 0.
1 parent 5359eda commit fe57bc5

4 files changed

Lines changed: 33 additions & 3 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
area: webapp
3+
type: feature
4+
---
5+
6+
New Sessions page in the dashboard for inspecting `chat.agent` Session rows alongside their underlying runs, plus a "Task source" filter on the Runs list (Standard / Scheduled / Agent) so agent runs can be sliced out of mixed workloads at a glance.

apps/webapp/app/routes/realtime.v1.sessions.$session.$io.records.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const SearchSchema = z.object({
3636
// `session_*` friendlyIds (which must reference a real row). External-id
3737
// form falls through with `row: null` so the boot path doesn't 404 on a
3838
// fresh chat that hasn't written its first chunk yet.
39-
const loader = createLoaderApiRoute(
39+
export const loader = createLoaderApiRoute(
4040
{
4141
params: ParamsSchema,
4242
searchParams: SearchSchema,
@@ -96,5 +96,3 @@ const loader = createLoaderApiRoute(
9696
return json({ records });
9797
}
9898
);
99-
100-
export { loader };

packages/core/src/v3/inputStreams/manager.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,25 @@ export class StandardInputStreamManager implements InputStreamManager {
192192
this.tails.delete(streamId);
193193
}
194194
this.buffer.delete(streamId);
195+
// Reset the backoff counter so a future re-attach starts fresh —
196+
// an explicit disconnect is a deliberate teardown, not evidence of
197+
// a broken backend.
198+
this.reconnectAttempts.delete(streamId);
195199
}
196200

197201
connectTail(runId: string, _fromSeq?: number): void {
198202
// No-op: tails are now created per-stream lazily
199203
}
200204

205+
/**
206+
* Tear down all active tails. Does NOT clear handlers or `onceWaiters`,
207+
* so any registered listener will trigger an auto-reconnect (with
208+
* backoff) the moment it sees no live tail — by design, so a transient
209+
* network blip recovers without the caller re-subscribing. Use
210+
* `reset()` if you want a full clean state with no resurrection, or
211+
* `disconnectStream(streamId)` for a single stream that should stay
212+
* down until a fresh `on()` / `once()` attaches.
213+
*/
201214
disconnect(): void {
202215
for (const [, tail] of this.tails) {
203216
tail.abortController.abort();

packages/core/src/v3/sessionStreams/manager.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ export class StandardSessionStreamManager implements SessionStreamManager {
217217
this.tails.delete(key);
218218
}
219219
this.buffer.delete(key);
220+
// Reset the backoff counter so a future re-attach starts fresh —
221+
// an explicit disconnect is a deliberate teardown, not evidence of
222+
// a broken backend.
223+
this.reconnectAttempts.delete(key);
220224
}
221225

222226
clearHandlers(): void {
@@ -231,6 +235,15 @@ export class StandardSessionStreamManager implements SessionStreamManager {
231235
}
232236
}
233237

238+
/**
239+
* Tear down all active tails. Does NOT clear handlers or `onceWaiters`,
240+
* so any registered listener will trigger an auto-reconnect (with
241+
* backoff) the moment it sees no live tail — by design, so a transient
242+
* network blip recovers without the caller re-subscribing. Use
243+
* `reset()` if you want a full clean state with no resurrection, or
244+
* `disconnectStream(sessionId, io)` for a single channel that should
245+
* stay down until a fresh `on()` / `once()` attaches.
246+
*/
234247
disconnect(): void {
235248
for (const [, tail] of this.tails) {
236249
tail.abortController.abort();

0 commit comments

Comments
 (0)