@truefoundry/assistant-ui-runtime 0.1.14 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +0 -1
- package/dist/index.js +73 -61
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/convertTurnMessages.test.ts +506 -44
- package/src/convertTurnMessages.ts +133 -85
- package/src/types.ts +0 -1
- package/src/useTrueFoundryAgentMessages.test.tsx +30 -26
- package/src/useTrueFoundryAgentMessages.ts +6 -13
- package/src/useTrueFoundryAgentRuntime.ts +0 -2
|
@@ -516,10 +516,6 @@ function attachRunningTurn(
|
|
|
516
516
|
if (runningTurn == null) {
|
|
517
517
|
return snapshot;
|
|
518
518
|
}
|
|
519
|
-
// Session-level history excludes the running turn. Apply continuation inputs
|
|
520
|
-
// from the turn listing so answered approvals / ask-user prompts are not
|
|
521
|
-
// restored as pending while reconnecting to that turn after a refresh.
|
|
522
|
-
applyUserToolResponsesToFold(snapshot.fold, runningTurn.input ?? []);
|
|
523
519
|
const pendingUserText = extractTurnUserText(runningTurn.input);
|
|
524
520
|
return replaceSessionSnapshot(snapshot, {
|
|
525
521
|
runningTurn,
|
|
@@ -537,13 +533,117 @@ function attachRunningTurn(
|
|
|
537
533
|
});
|
|
538
534
|
}
|
|
539
535
|
|
|
536
|
+
/**
|
|
537
|
+
* Last `turn.created` in ASC event order with no following `turn.done` — the
|
|
538
|
+
* open tip of the active branch in this window.
|
|
539
|
+
*/
|
|
540
|
+
function findOpenTurnCreated(
|
|
541
|
+
itemsAsc: readonly GatewaySessionEventItem[],
|
|
542
|
+
): { turnId: string; event: TurnCreatedEvent } | undefined {
|
|
543
|
+
let open: { turnId: string; event: TurnCreatedEvent } | undefined;
|
|
544
|
+
for (const item of itemsAsc) {
|
|
545
|
+
if (item.event.type === "turn.created") {
|
|
546
|
+
open = { turnId: item.turnId, event: item.event };
|
|
547
|
+
} else if (item.event.type === "turn.done") {
|
|
548
|
+
open = undefined;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return open;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
function turnFromCreatedEvent(options: {
|
|
555
|
+
sessionId: string;
|
|
556
|
+
turnId: string;
|
|
557
|
+
event: TurnCreatedEvent;
|
|
558
|
+
}): Turn {
|
|
559
|
+
const { sessionId, turnId, event } = options;
|
|
560
|
+
return {
|
|
561
|
+
id: turnId,
|
|
562
|
+
sessionId,
|
|
563
|
+
state: { status: "running" },
|
|
564
|
+
createdAt: event.createdAt,
|
|
565
|
+
...(event.input != null ? { input: event.input } : {}),
|
|
566
|
+
...(event.previousTurnId === undefined
|
|
567
|
+
? {}
|
|
568
|
+
: { previousTurnId: event.previousTurnId }),
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
type SessionTip = {
|
|
573
|
+
/** Turn to resume and subscribe to; absent once the tip has finished. */
|
|
574
|
+
runningTurn?: Turn;
|
|
575
|
+
/**
|
|
576
|
+
* Tip input that event ingestion could not apply, because it only folds a
|
|
577
|
+
* turn's input once that turn's `turn.done` arrives. Answered ask-user
|
|
578
|
+
* prompts and approvals live here, so this must be folded even when the tip
|
|
579
|
+
* is no longer running.
|
|
580
|
+
*/
|
|
581
|
+
continuationInput: readonly TurnInputItem[];
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Resolves the tip turn of the active branch for resume/subscribe.
|
|
586
|
+
*
|
|
587
|
+
* Prefer an open tip from the events window (works when listTurns is
|
|
588
|
+
* oldest-first and when listEvents includes the running turn). Fall back to
|
|
589
|
+
* `listTurns({ limit: 1 })` for hosts that omit the running turn from
|
|
590
|
+
* listEvents and put the tip first.
|
|
591
|
+
*/
|
|
592
|
+
async function resolveSessionTip(options: {
|
|
593
|
+
server: AgentChatServer;
|
|
594
|
+
sessionId: string;
|
|
595
|
+
itemsAsc: readonly GatewaySessionEventItem[];
|
|
596
|
+
}): Promise<SessionTip> {
|
|
597
|
+
const { server, sessionId, itemsAsc } = options;
|
|
598
|
+
const open = findOpenTurnCreated(itemsAsc);
|
|
599
|
+
if (open != null) {
|
|
600
|
+
const continuationInput = open.event.input ?? [];
|
|
601
|
+
if (typeof server.getTurn === "function") {
|
|
602
|
+
try {
|
|
603
|
+
const turn = await server.getTurn({
|
|
604
|
+
sessionId,
|
|
605
|
+
turnId: open.turnId,
|
|
606
|
+
});
|
|
607
|
+
if (turn.state.status === "running") {
|
|
608
|
+
return {
|
|
609
|
+
runningTurn: turn,
|
|
610
|
+
continuationInput: turn.input ?? continuationInput,
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
// Tip finished between listEvents and getTurn: nothing to
|
|
614
|
+
// resume, but its answers still belong in the fold.
|
|
615
|
+
return { continuationInput: turn.input ?? continuationInput };
|
|
616
|
+
} catch {
|
|
617
|
+
// getTurn failed; synthesize from the open turn.created below.
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
return {
|
|
621
|
+
runningTurn: turnFromCreatedEvent({
|
|
622
|
+
sessionId,
|
|
623
|
+
turnId: open.turnId,
|
|
624
|
+
event: open.event,
|
|
625
|
+
}),
|
|
626
|
+
continuationInput,
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
// Hosts that exclude the running turn from listEvents still surface it as
|
|
631
|
+
// the first row of listTurns when that API is tip-first.
|
|
632
|
+
const turnsPage = await server.listTurns({ sessionId, limit: 1 });
|
|
633
|
+
const tip = turnsPage.data[0] as Turn | undefined;
|
|
634
|
+
return tip?.state?.status === "running"
|
|
635
|
+
? { runningTurn: tip, continuationInput: tip.input ?? [] }
|
|
636
|
+
: { continuationInput: [] };
|
|
637
|
+
}
|
|
638
|
+
|
|
540
639
|
/**
|
|
541
640
|
* Builds a session snapshot using the session-level `listEvents` API.
|
|
542
641
|
*
|
|
543
642
|
* Loads the newest event page (extending only when a page boundary splits a
|
|
544
643
|
* turn group), then leaves older pages for `prependOlderSessionHistory`.
|
|
545
|
-
*
|
|
546
|
-
*
|
|
644
|
+
* Detects a currently-running tip from an open `turn.created` in that window
|
|
645
|
+
* when present; otherwise falls back to `listTurns({ limit: 1 })` for hosts
|
|
646
|
+
* that omit the running turn from listEvents.
|
|
547
647
|
*
|
|
548
648
|
* `onProgress` is called after each complete turn is ingested so callers can
|
|
549
649
|
* update the UI progressively while the processing loop runs.
|
|
@@ -553,12 +653,6 @@ export async function buildSnapshotFromSessionEvents(
|
|
|
553
653
|
sessionId: string,
|
|
554
654
|
onProgress?: (snap: SessionSnapshot) => void,
|
|
555
655
|
): Promise<SessionSnapshot> {
|
|
556
|
-
// Detect a running turn with a single listTurns page — do not drain pagination.
|
|
557
|
-
const turnsPage = await server.listTurns({ sessionId, limit: 1 });
|
|
558
|
-
const newestTurn = turnsPage.data[0] as Turn | undefined;
|
|
559
|
-
const runningTurn =
|
|
560
|
-
newestTurn?.state?.status === "running" ? newestTurn : undefined;
|
|
561
|
-
|
|
562
656
|
const window = await fetchSessionEventsWindow(server, sessionId);
|
|
563
657
|
const historyPagination: SessionHistoryPagination = {
|
|
564
658
|
hasOlder: window.hasOlder,
|
|
@@ -575,7 +669,16 @@ export async function buildSnapshotFromSessionEvents(
|
|
|
575
669
|
historyPagination,
|
|
576
670
|
});
|
|
577
671
|
|
|
578
|
-
|
|
672
|
+
const tip = await resolveSessionTip({
|
|
673
|
+
server,
|
|
674
|
+
sessionId,
|
|
675
|
+
itemsAsc: window.itemsAsc,
|
|
676
|
+
});
|
|
677
|
+
// The tip has no turn.done in this window, so ingestion never folded its
|
|
678
|
+
// input. Apply it here so answered approvals / ask-user prompts are not
|
|
679
|
+
// restored as pending after a refresh.
|
|
680
|
+
applyUserToolResponsesToFold(withHistory.fold, tip.continuationInput);
|
|
681
|
+
return attachRunningTurn(withHistory, tip.runningTurn);
|
|
579
682
|
}
|
|
580
683
|
|
|
581
684
|
/**
|
|
@@ -1276,93 +1379,38 @@ export async function buildSnapshotFromSession(
|
|
|
1276
1379
|
});
|
|
1277
1380
|
}
|
|
1278
1381
|
|
|
1279
|
-
/**
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
): Promise<SessionSnapshot> {
|
|
1286
|
-
const turns = await listSessionTurnsOrdered(server, sessionId);
|
|
1287
|
-
|
|
1288
|
-
const beforeIndex = turns.findIndex((turn) => turn.id === beforeTurnId);
|
|
1289
|
-
if (beforeIndex === -1) {
|
|
1290
|
-
throw new Error(`Turn ${beforeTurnId} not found in session`);
|
|
1291
|
-
}
|
|
1292
|
-
|
|
1293
|
-
return buildSnapshotBeforeTurnIndex(
|
|
1294
|
-
server,
|
|
1295
|
-
sessionId,
|
|
1296
|
-
beforeIndex,
|
|
1297
|
-
concurrency,
|
|
1298
|
-
turns,
|
|
1299
|
-
);
|
|
1300
|
-
}
|
|
1301
|
-
|
|
1302
|
-
/** Rebuilds session state from the first `turnIndex` turns (excludes that turn). */
|
|
1303
|
-
export async function buildSnapshotBeforeTurnIndex(
|
|
1382
|
+
/**
|
|
1383
|
+
* Rebuilds the conversation through `anchorTurnId`, including that turn.
|
|
1384
|
+
* The server follows parent links from the anchor, so turns from abandoned
|
|
1385
|
+
* branches are excluded. A null anchor represents an empty conversation.
|
|
1386
|
+
*/
|
|
1387
|
+
export async function buildSnapshotThroughTurn(
|
|
1304
1388
|
server: AgentChatServer,
|
|
1305
1389
|
sessionId: string,
|
|
1306
|
-
|
|
1307
|
-
_concurrency: number = DEFAULT_LIST_EVENTS_CONCURRENCY,
|
|
1308
|
-
orderedTurns?: Turn[],
|
|
1390
|
+
anchorTurnId: string | null,
|
|
1309
1391
|
): Promise<SessionSnapshot> {
|
|
1310
|
-
if (
|
|
1392
|
+
if (anchorTurnId == null) {
|
|
1311
1393
|
return createEmptySessionSnapshot();
|
|
1312
1394
|
}
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
const lastTurnId = turnsToInclude.at(-1)?.id;
|
|
1317
|
-
if (lastTurnId == null) {
|
|
1318
|
-
return createEmptySessionSnapshot();
|
|
1319
|
-
}
|
|
1320
|
-
|
|
1321
|
-
// Anchor the session events window at the newest included turn so the
|
|
1322
|
-
// ancestor chain matches `[turns[0], …, turns[turnIndex - 1]]`.
|
|
1323
|
-
const items = await fetchAllSessionEvents(server, sessionId, { lastTurnId });
|
|
1395
|
+
const items = await fetchAllSessionEvents(server, sessionId, {
|
|
1396
|
+
lastTurnId: anchorTurnId,
|
|
1397
|
+
});
|
|
1324
1398
|
const snapshot = createEmptySessionSnapshot();
|
|
1325
1399
|
ingestSessionEventsIntoSnapshot(snapshot, items);
|
|
1326
1400
|
return snapshot;
|
|
1327
1401
|
}
|
|
1328
1402
|
|
|
1329
|
-
/**
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
turnIndex: number,
|
|
1334
|
-
orderedTurns?: Turn[],
|
|
1335
|
-
): Promise<string> {
|
|
1336
|
-
if (turnIndex <= 0) {
|
|
1337
|
-
return "none";
|
|
1338
|
-
}
|
|
1339
|
-
const turns = orderedTurns ?? (await listSessionTurnsOrdered(server, sessionId));
|
|
1340
|
-
return turns[turnIndex - 1]?.id ?? "none";
|
|
1341
|
-
}
|
|
1342
|
-
|
|
1343
|
-
/** Resolves `previousTurnId` by turn id so partial history windows stay correct. */
|
|
1403
|
+
/**
|
|
1404
|
+
* Resolves `previousTurnId` for edit/retry of `turnId` from the turn's own
|
|
1405
|
+
* parent pointer (`"none"` for roots). Independent of listTurns order.
|
|
1406
|
+
*/
|
|
1344
1407
|
export async function resolveGatewayBranchPreviousTurnIdForTurn(
|
|
1345
1408
|
server: AgentChatServer,
|
|
1346
1409
|
sessionId: string,
|
|
1347
1410
|
turnId: string,
|
|
1348
1411
|
): Promise<string> {
|
|
1349
|
-
const
|
|
1350
|
-
|
|
1351
|
-
return resolveGatewayBranchPreviousTurnId(server, sessionId, turnIndex, turns);
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
async function listSessionTurnsOrdered(
|
|
1355
|
-
server: AgentChatServer,
|
|
1356
|
-
sessionId: string,
|
|
1357
|
-
): Promise<Turn[]> {
|
|
1358
|
-
const turns = await drainListPages((pageToken) =>
|
|
1359
|
-
server.listTurns({
|
|
1360
|
-
sessionId,
|
|
1361
|
-
...(pageToken != null ? { pageToken } : {}),
|
|
1362
|
-
}),
|
|
1363
|
-
);
|
|
1364
|
-
turns.reverse();
|
|
1365
|
-
return turns;
|
|
1412
|
+
const turn = await server.getTurn({ sessionId, turnId });
|
|
1413
|
+
return turn.previousTurnId ?? "none";
|
|
1366
1414
|
}
|
|
1367
1415
|
|
|
1368
1416
|
export async function buildTurnAssistantContent(
|
package/src/types.ts
CHANGED
|
@@ -28,7 +28,6 @@ type TrueFoundryAgentRuntimeBaseOptions = ExternalStoreSharedOptions & {
|
|
|
28
28
|
threadId?: string | undefined;
|
|
29
29
|
onThreadIdChange?: ((threadId: string | undefined) => void) | undefined;
|
|
30
30
|
onError?: ((error: unknown) => void) | undefined;
|
|
31
|
-
listEventsConcurrency?: number | undefined;
|
|
32
31
|
/**
|
|
33
32
|
* Optional filter forwarded to `listSessions({ agentId })`.
|
|
34
33
|
* Omit for all chats; hosts that key agents by name pass that name as the id.
|
|
@@ -47,6 +47,7 @@ vi.mock("./convertTurnMessages.js", async (importOriginal) => {
|
|
|
47
47
|
const mockServer = {
|
|
48
48
|
cancelSession: vi.fn().mockResolvedValue(undefined),
|
|
49
49
|
listTurns: vi.fn(),
|
|
50
|
+
getTurn: vi.fn(),
|
|
50
51
|
// Present so resume-capable paths are exercised; resumeTurnStream is mocked.
|
|
51
52
|
subscribeToTurn: vi.fn(),
|
|
52
53
|
} as unknown as AgentChatServer;
|
|
@@ -429,6 +430,7 @@ describe("useTrueFoundryAgentMessages", () => {
|
|
|
429
430
|
expect.any(PeerThreadFoldState),
|
|
430
431
|
{
|
|
431
432
|
userMessage: "first",
|
|
433
|
+
previousTurnId: "none",
|
|
432
434
|
headers: {
|
|
433
435
|
"x-tfy-session-last-updated-at": "2026-06-30T12:00:00.000Z",
|
|
434
436
|
},
|
|
@@ -689,21 +691,22 @@ describe("useTrueFoundryAgentMessages", () => {
|
|
|
689
691
|
|
|
690
692
|
it("editFromTurn drops prior turns before showing the edited user message", async () => {
|
|
691
693
|
const createdAt = new Date().toISOString();
|
|
694
|
+
const rootTurn = {
|
|
695
|
+
id: "turn-1",
|
|
696
|
+
sessionId: "session-1",
|
|
697
|
+
createdAt,
|
|
698
|
+
previousTurnId: null,
|
|
699
|
+
state: {
|
|
700
|
+
status: "done" as const,
|
|
701
|
+
requiredActions: [],
|
|
702
|
+
completedAt: createdAt,
|
|
703
|
+
},
|
|
704
|
+
input: [{ type: "user.message" as const, content: "Hello" }],
|
|
705
|
+
} as Turn;
|
|
692
706
|
vi.mocked(mockServer.listTurns).mockResolvedValue({
|
|
693
|
-
data: [
|
|
694
|
-
{
|
|
695
|
-
id: "turn-1",
|
|
696
|
-
sessionId: "session-1",
|
|
697
|
-
createdAt,
|
|
698
|
-
state: {
|
|
699
|
-
status: "done",
|
|
700
|
-
requiredActions: [],
|
|
701
|
-
completedAt: createdAt,
|
|
702
|
-
},
|
|
703
|
-
input: [{ type: "user.message", content: "Hello" }],
|
|
704
|
-
} as Turn,
|
|
705
|
-
],
|
|
707
|
+
data: [rootTurn],
|
|
706
708
|
});
|
|
709
|
+
vi.mocked(mockServer.getTurn).mockResolvedValue(rootTurn);
|
|
707
710
|
const fold = new PeerThreadFoldState();
|
|
708
711
|
ingestTurnEvent(fold, {
|
|
709
712
|
type: "model.message",
|
|
@@ -805,21 +808,22 @@ describe("useTrueFoundryAgentMessages", () => {
|
|
|
805
808
|
const onError = vi.fn();
|
|
806
809
|
const original = snapshotWithUserTurn("Hello");
|
|
807
810
|
vi.mocked(loadSessionSnapshot).mockResolvedValue(original);
|
|
811
|
+
const rootTurn = {
|
|
812
|
+
id: "turn-1",
|
|
813
|
+
sessionId: "session-1",
|
|
814
|
+
createdAt,
|
|
815
|
+
previousTurnId: null,
|
|
816
|
+
state: {
|
|
817
|
+
status: "done" as const,
|
|
818
|
+
requiredActions: [],
|
|
819
|
+
completedAt: createdAt,
|
|
820
|
+
},
|
|
821
|
+
input: [{ type: "user.message" as const, content: "Hello" }],
|
|
822
|
+
} as Turn;
|
|
808
823
|
vi.mocked(mockServer.listTurns).mockResolvedValue({
|
|
809
|
-
data: [
|
|
810
|
-
{
|
|
811
|
-
id: "turn-1",
|
|
812
|
-
sessionId: "session-1",
|
|
813
|
-
createdAt,
|
|
814
|
-
state: {
|
|
815
|
-
status: "done",
|
|
816
|
-
requiredActions: [],
|
|
817
|
-
completedAt: createdAt,
|
|
818
|
-
},
|
|
819
|
-
input: [{ type: "user.message", content: "Hello" }],
|
|
820
|
-
} as Turn,
|
|
821
|
-
],
|
|
824
|
+
data: [rootTurn],
|
|
822
825
|
});
|
|
826
|
+
vi.mocked(mockServer.getTurn).mockResolvedValue(rootTurn);
|
|
823
827
|
vi.mocked(streamTurnContent).mockImplementation(async function* () {
|
|
824
828
|
throw new Error("Turn preparation failed");
|
|
825
829
|
});
|
|
@@ -15,7 +15,7 @@ import type { AgentChatServer } from "./server/types.js";
|
|
|
15
15
|
import { ROOT_THREAD_ID } from "./constants.js";
|
|
16
16
|
import {
|
|
17
17
|
buildEditedUserMessageContent,
|
|
18
|
-
|
|
18
|
+
buildSnapshotThroughTurn,
|
|
19
19
|
computeGroupRootBaseline,
|
|
20
20
|
extractTurnUserMessageContent,
|
|
21
21
|
prependOlderSessionHistory,
|
|
@@ -60,7 +60,6 @@ export type UseTrueFoundryAgentMessagesOptions = {
|
|
|
60
60
|
isMain?: boolean | undefined;
|
|
61
61
|
/** URL-selected session may load before the thread list marks it as main. */
|
|
62
62
|
isInitialSession?: boolean | undefined;
|
|
63
|
-
listEventsConcurrency?: number | undefined;
|
|
64
63
|
onError?: ((error: unknown) => void) | undefined;
|
|
65
64
|
initializeSession?: () => Promise<{
|
|
66
65
|
remoteId: string;
|
|
@@ -293,7 +292,6 @@ export function useTrueFoundryAgentMessages({
|
|
|
293
292
|
sessionId,
|
|
294
293
|
isMain,
|
|
295
294
|
isInitialSession,
|
|
296
|
-
listEventsConcurrency,
|
|
297
295
|
onError,
|
|
298
296
|
initializeSession,
|
|
299
297
|
resolveConversationSessionId,
|
|
@@ -975,11 +973,12 @@ export function useTrueFoundryAgentMessages({
|
|
|
975
973
|
conversationSessionId,
|
|
976
974
|
turnId,
|
|
977
975
|
);
|
|
978
|
-
|
|
976
|
+
// Rewind to the exact parent used for the new branch. Using the
|
|
977
|
+
// previous item from listTurns could select an abandoned branch.
|
|
978
|
+
rewound = await buildSnapshotThroughTurn(
|
|
979
979
|
server,
|
|
980
980
|
conversationSessionId,
|
|
981
|
-
|
|
982
|
-
listEventsConcurrency,
|
|
981
|
+
previousTurnId === "none" ? null : previousTurnId,
|
|
983
982
|
);
|
|
984
983
|
createdAtByMessageIdRef.current = new Map();
|
|
985
984
|
// Keep the ref aligned before awaiting sendTurn so any intermediate
|
|
@@ -1000,13 +999,7 @@ export function useTrueFoundryAgentMessages({
|
|
|
1000
999
|
branchRollbackSnapshot: committed,
|
|
1001
1000
|
});
|
|
1002
1001
|
},
|
|
1003
|
-
[
|
|
1004
|
-
cancel,
|
|
1005
|
-
server,
|
|
1006
|
-
listEventsConcurrency,
|
|
1007
|
-
sendTurn,
|
|
1008
|
-
sessionId,
|
|
1009
|
-
],
|
|
1002
|
+
[cancel, server, sendTurn, sessionId],
|
|
1010
1003
|
);
|
|
1011
1004
|
|
|
1012
1005
|
const resetFromTurn = useCallback(
|
|
@@ -49,7 +49,6 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
49
49
|
agent,
|
|
50
50
|
adapters,
|
|
51
51
|
onError,
|
|
52
|
-
listEventsConcurrency,
|
|
53
52
|
...sharedOptions
|
|
54
53
|
} = options;
|
|
55
54
|
|
|
@@ -126,7 +125,6 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
126
125
|
sessionId,
|
|
127
126
|
isMain,
|
|
128
127
|
isInitialSession,
|
|
129
|
-
listEventsConcurrency,
|
|
130
128
|
onError,
|
|
131
129
|
initializeSession,
|
|
132
130
|
getTurnHeaders: agent.mode === "draft" ? getTurnHeaders : undefined,
|