@truefoundry/assistant-ui-runtime 0.1.1 → 0.1.3-rc.1

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.js CHANGED
@@ -1304,6 +1304,280 @@ function replaceSessionSnapshot(snapshot, patch) {
1304
1304
  // src/convertTurnMessages.ts
1305
1305
  var TURN_EVENTS_PAGE_SIZE = 25;
1306
1306
  var SESSION_EVENTS_PAGE_SIZE = 100;
1307
+ var MAX_HISTORY_BOUNDARY_PAGES = 10;
1308
+ function trimIncompleteLeadingEvents(itemsAsc) {
1309
+ const start = itemsAsc.findIndex((item) => item.event.type === "turn.created");
1310
+ if (start === -1) {
1311
+ return [];
1312
+ }
1313
+ return itemsAsc.slice(start);
1314
+ }
1315
+ function oldestCompleteTurnGroupState(itemsAsc) {
1316
+ const trimmed = trimIncompleteLeadingEvents(itemsAsc);
1317
+ if (trimmed.length === 0) {
1318
+ return "incomplete";
1319
+ }
1320
+ const created = trimmed[0];
1321
+ if (created?.event.type !== "turn.created") {
1322
+ return "incomplete";
1323
+ }
1324
+ const hasDone = trimmed.some(
1325
+ (item) => item.turnId === created.turnId && item.event.type === "turn.done"
1326
+ );
1327
+ if (!hasDone) {
1328
+ return "incomplete";
1329
+ }
1330
+ return extractTurnUserText(created.event.input) != null ? "user-group" : "continuation";
1331
+ }
1332
+ async function fetchSessionEventsPage(session, options) {
1333
+ const page = await session.listEvents({
1334
+ limit: SESSION_EVENTS_PAGE_SIZE,
1335
+ ...options?.lastTurnId != null ? { lastTurnId: options.lastTurnId } : {},
1336
+ ...options?.pageToken != null ? { pageToken: options.pageToken } : {}
1337
+ });
1338
+ const response = page.response;
1339
+ const olderPageToken = response.pagination?.nextPageToken;
1340
+ const hasOlder = typeof page.hasNextPage === "function" ? page.hasNextPage() : olderPageToken != null && olderPageToken !== "";
1341
+ return {
1342
+ itemsNewestFirst: page.data,
1343
+ ...olderPageToken != null && olderPageToken !== "" ? { olderPageToken } : {},
1344
+ hasOlder
1345
+ };
1346
+ }
1347
+ async function fetchSessionEventsWindow(session, options) {
1348
+ let itemsNewestFirst = [];
1349
+ let pageToken = options?.pageToken;
1350
+ let olderPageToken;
1351
+ let hasOlder = false;
1352
+ for (let pageCount = 0; pageCount < MAX_HISTORY_BOUNDARY_PAGES; pageCount++) {
1353
+ const page = await fetchSessionEventsPage(session, {
1354
+ ...options,
1355
+ ...pageToken != null ? { pageToken } : {}
1356
+ });
1357
+ itemsNewestFirst = [...itemsNewestFirst, ...page.itemsNewestFirst];
1358
+ olderPageToken = page.olderPageToken;
1359
+ hasOlder = page.hasOlder;
1360
+ const itemsAsc2 = trimIncompleteLeadingEvents([...itemsNewestFirst].reverse());
1361
+ const groupState = oldestCompleteTurnGroupState(itemsAsc2);
1362
+ if (groupState === "user-group" || !hasOlder) {
1363
+ return {
1364
+ itemsAsc: itemsAsc2,
1365
+ ...olderPageToken != null ? { olderPageToken } : {},
1366
+ hasOlder
1367
+ };
1368
+ }
1369
+ if (olderPageToken == null) {
1370
+ return { itemsAsc: itemsAsc2, hasOlder: false };
1371
+ }
1372
+ pageToken = olderPageToken;
1373
+ }
1374
+ const itemsAsc = trimIncompleteLeadingEvents([...itemsNewestFirst].reverse());
1375
+ return {
1376
+ itemsAsc,
1377
+ ...olderPageToken != null ? { olderPageToken } : {},
1378
+ hasOlder
1379
+ };
1380
+ }
1381
+ async function fetchAllSessionEvents(session, options) {
1382
+ const items = [];
1383
+ for await (const item of await session.listEvents({
1384
+ limit: SESSION_EVENTS_PAGE_SIZE,
1385
+ ...options?.lastTurnId != null ? { lastTurnId: options.lastTurnId } : {}
1386
+ })) {
1387
+ items.push(item);
1388
+ }
1389
+ items.reverse();
1390
+ return items;
1391
+ }
1392
+ function cloneThreadBucket(bucket) {
1393
+ return {
1394
+ events: new Map(bucket.events),
1395
+ modelMessageIds: [...bucket.modelMessageIds],
1396
+ toolResults: new Map(bucket.toolResults),
1397
+ pendingApprovals: new Map(bucket.pendingApprovals),
1398
+ approvalDecisions: new Map(bucket.approvalDecisions),
1399
+ pendingResponses: new Map(bucket.pendingResponses),
1400
+ done: bucket.done,
1401
+ ...bucket.title != null ? { title: bucket.title } : {},
1402
+ ...bucket.agentInfo != null ? { agentInfo: bucket.agentInfo } : {}
1403
+ };
1404
+ }
1405
+ function prependFoldState(older, newer) {
1406
+ const result = new PeerThreadFoldState();
1407
+ const threadIds = /* @__PURE__ */ new Set([...older.threads.keys(), ...newer.threads.keys()]);
1408
+ for (const threadId of threadIds) {
1409
+ const olderBucket = older.threads.get(threadId);
1410
+ const newerBucket = newer.threads.get(threadId);
1411
+ if (olderBucket == null && newerBucket != null) {
1412
+ result.threads.set(threadId, cloneThreadBucket(newerBucket));
1413
+ continue;
1414
+ }
1415
+ if (newerBucket == null && olderBucket != null) {
1416
+ result.threads.set(threadId, cloneThreadBucket(olderBucket));
1417
+ continue;
1418
+ }
1419
+ if (olderBucket == null || newerBucket == null) {
1420
+ continue;
1421
+ }
1422
+ result.threads.set(threadId, {
1423
+ events: new Map([...olderBucket.events, ...newerBucket.events]),
1424
+ modelMessageIds: [
1425
+ ...olderBucket.modelMessageIds,
1426
+ ...newerBucket.modelMessageIds
1427
+ ],
1428
+ toolResults: new Map([
1429
+ ...olderBucket.toolResults,
1430
+ ...newerBucket.toolResults
1431
+ ]),
1432
+ pendingApprovals: new Map([
1433
+ ...olderBucket.pendingApprovals,
1434
+ ...newerBucket.pendingApprovals
1435
+ ]),
1436
+ approvalDecisions: new Map([
1437
+ ...olderBucket.approvalDecisions,
1438
+ ...newerBucket.approvalDecisions
1439
+ ]),
1440
+ pendingResponses: new Map([
1441
+ ...olderBucket.pendingResponses,
1442
+ ...newerBucket.pendingResponses
1443
+ ]),
1444
+ done: newerBucket.done || olderBucket.done,
1445
+ ...newerBucket.title != null || olderBucket.title != null ? { title: newerBucket.title ?? olderBucket.title } : {},
1446
+ ...newerBucket.agentInfo != null || olderBucket.agentInfo != null ? { agentInfo: newerBucket.agentInfo ?? olderBucket.agentInfo } : {}
1447
+ });
1448
+ }
1449
+ for (const [threadId, link] of older.threadParents) {
1450
+ result.threadParents.set(threadId, link);
1451
+ }
1452
+ for (const [threadId, link] of newer.threadParents) {
1453
+ result.threadParents.set(threadId, link);
1454
+ }
1455
+ return result;
1456
+ }
1457
+ function ingestSessionEventsIntoSnapshot(snapshot, items, onTurnComplete) {
1458
+ let currentTurnId = null;
1459
+ let currentCreatedEvent = null;
1460
+ let currentContentEvents = [];
1461
+ let beforeCount = 0;
1462
+ for (const item of items) {
1463
+ const { turnId, event } = item;
1464
+ if (event.type === "turn.created") {
1465
+ currentTurnId = turnId;
1466
+ currentCreatedEvent = event;
1467
+ currentContentEvents = [];
1468
+ beforeCount = snapshot.fold.threads.get(ROOT_THREAD_ID)?.modelMessageIds.length ?? 0;
1469
+ } else if (event.type === "turn.done") {
1470
+ if (currentTurnId == null || currentCreatedEvent == null) {
1471
+ continue;
1472
+ }
1473
+ const afterBucket = snapshot.fold.threads.get(ROOT_THREAD_ID);
1474
+ const rootModelMessageIds = (afterBucket?.modelMessageIds ?? []).slice(
1475
+ beforeCount
1476
+ );
1477
+ const sandboxEvent = currentContentEvents.find(
1478
+ (ev) => ev.type === "sandbox.created"
1479
+ );
1480
+ applyUserToolResponsesToFold(
1481
+ snapshot.fold,
1482
+ currentCreatedEvent.input ?? []
1483
+ );
1484
+ snapshot.turns.push(
1485
+ sessionEventsToSessionRecord(
1486
+ currentTurnId,
1487
+ currentCreatedEvent,
1488
+ event,
1489
+ rootModelMessageIds,
1490
+ sandboxEvent?.sandboxId
1491
+ )
1492
+ );
1493
+ onTurnComplete?.(replaceSessionSnapshot(snapshot, {}));
1494
+ currentTurnId = null;
1495
+ currentCreatedEvent = null;
1496
+ currentContentEvents = [];
1497
+ } else {
1498
+ if (currentTurnId != null) {
1499
+ ingestTurnEvent(snapshot.fold, event);
1500
+ currentContentEvents.push(event);
1501
+ }
1502
+ }
1503
+ }
1504
+ }
1505
+ function attachRunningTurn(snapshot, runningTurn) {
1506
+ if (runningTurn == null) {
1507
+ return snapshot;
1508
+ }
1509
+ const pendingUserText = extractTurnUserText(runningTurn.input);
1510
+ return replaceSessionSnapshot(snapshot, {
1511
+ runningTurn,
1512
+ unstable_resume: true,
1513
+ groupRootBaseline: computeGroupRootBaseline(snapshot.turns),
1514
+ ...pendingUserText ? {
1515
+ pendingUser: {
1516
+ turnId: runningTurn.id,
1517
+ content: extractTurnUserMessageContent(runningTurn.input),
1518
+ createdAt: new Date(runningTurn.createdAt)
1519
+ }
1520
+ } : {}
1521
+ });
1522
+ }
1523
+ async function buildSnapshotFromSessionEvents(session, onProgress) {
1524
+ const turnsPage = await session.listTurns({ limit: 1 });
1525
+ const newestTurn = turnsPage.data[0];
1526
+ const runningTurn = newestTurn?.state?.status === "running" ? newestTurn : void 0;
1527
+ const window = await fetchSessionEventsWindow(session);
1528
+ const historyPagination = {
1529
+ hasOlder: window.hasOlder,
1530
+ ...window.olderPageToken != null ? { olderPageToken: window.olderPageToken } : {}
1531
+ };
1532
+ const snapshot = createEmptySessionSnapshot();
1533
+ ingestSessionEventsIntoSnapshot(snapshot, window.itemsAsc, onProgress);
1534
+ const withHistory = replaceSessionSnapshot(snapshot, {
1535
+ historyEvents: window.itemsAsc,
1536
+ historyPagination
1537
+ });
1538
+ return attachRunningTurn(withHistory, runningTurn);
1539
+ }
1540
+ async function prependOlderSessionHistory(session, snapshot) {
1541
+ const pagination = snapshot.historyPagination;
1542
+ if (pagination?.hasOlder !== true || pagination.olderPageToken == null) {
1543
+ return snapshot;
1544
+ }
1545
+ const window = await fetchSessionEventsWindow(session, {
1546
+ pageToken: pagination.olderPageToken
1547
+ });
1548
+ if (window.itemsAsc.length === 0) {
1549
+ return replaceSessionSnapshot(snapshot, {
1550
+ historyPagination: { hasOlder: false }
1551
+ });
1552
+ }
1553
+ const olderSnap = createEmptySessionSnapshot();
1554
+ ingestSessionEventsIntoSnapshot(olderSnap, window.itemsAsc);
1555
+ const existingIds = new Set(snapshot.turns.map((turn) => turn.id));
1556
+ const olderTurns = olderSnap.turns.filter((turn) => !existingIds.has(turn.id));
1557
+ const mergedFold = prependFoldState(olderSnap.fold, snapshot.fold);
1558
+ const historyEvents = [
1559
+ ...window.itemsAsc,
1560
+ ...snapshot.historyEvents ?? []
1561
+ ];
1562
+ const olderRootIds = olderTurns.flatMap(
1563
+ (turn) => turn.rootModelMessageIds ?? []
1564
+ );
1565
+ return replaceSessionSnapshot(snapshot, {
1566
+ fold: mergedFold,
1567
+ turns: [...olderTurns, ...snapshot.turns],
1568
+ historyEvents,
1569
+ historyPagination: {
1570
+ hasOlder: window.hasOlder,
1571
+ ...window.olderPageToken != null ? { olderPageToken: window.olderPageToken } : {}
1572
+ },
1573
+ ...snapshot.groupRootBaseline != null ? {
1574
+ groupRootBaseline: [
1575
+ ...olderRootIds,
1576
+ ...snapshot.groupRootBaseline
1577
+ ]
1578
+ } : {}
1579
+ });
1580
+ }
1307
1581
  function assistantStatusFromTurnState(state) {
1308
1582
  switch (state.status) {
1309
1583
  case "done":
@@ -1710,92 +1984,6 @@ function projectSessionMessages(snapshot, options) {
1710
1984
  );
1711
1985
  }
1712
1986
  var DEFAULT_LIST_EVENTS_CONCURRENCY = 5;
1713
- async function fetchAllSessionEvents(session, options) {
1714
- const items = [];
1715
- for await (const item of await session.listEvents({
1716
- limit: SESSION_EVENTS_PAGE_SIZE,
1717
- ...options?.lastTurnId != null ? { lastTurnId: options.lastTurnId } : {}
1718
- })) {
1719
- items.push(item);
1720
- }
1721
- items.reverse();
1722
- return items;
1723
- }
1724
- function ingestSessionEventsIntoSnapshot(snapshot, items, onTurnComplete) {
1725
- let currentTurnId = null;
1726
- let currentCreatedEvent = null;
1727
- let currentContentEvents = [];
1728
- let beforeCount = 0;
1729
- for (const item of items) {
1730
- const { turnId, event } = item;
1731
- if (event.type === "turn.created") {
1732
- currentTurnId = turnId;
1733
- currentCreatedEvent = event;
1734
- currentContentEvents = [];
1735
- beforeCount = snapshot.fold.threads.get(ROOT_THREAD_ID)?.modelMessageIds.length ?? 0;
1736
- } else if (event.type === "turn.done") {
1737
- if (currentTurnId == null || currentCreatedEvent == null) {
1738
- continue;
1739
- }
1740
- const afterBucket = snapshot.fold.threads.get(ROOT_THREAD_ID);
1741
- const rootModelMessageIds = (afterBucket?.modelMessageIds ?? []).slice(
1742
- beforeCount
1743
- );
1744
- const sandboxEvent = currentContentEvents.find(
1745
- (ev) => ev.type === "sandbox.created"
1746
- );
1747
- applyUserToolResponsesToFold(
1748
- snapshot.fold,
1749
- currentCreatedEvent.input ?? []
1750
- );
1751
- snapshot.turns.push(
1752
- sessionEventsToSessionRecord(
1753
- currentTurnId,
1754
- currentCreatedEvent,
1755
- event,
1756
- rootModelMessageIds,
1757
- sandboxEvent?.sandboxId
1758
- )
1759
- );
1760
- onTurnComplete?.(replaceSessionSnapshot(snapshot, {}));
1761
- currentTurnId = null;
1762
- currentCreatedEvent = null;
1763
- currentContentEvents = [];
1764
- } else {
1765
- if (currentTurnId != null) {
1766
- ingestTurnEvent(snapshot.fold, event);
1767
- currentContentEvents.push(event);
1768
- }
1769
- }
1770
- }
1771
- }
1772
- async function buildSnapshotFromSessionEvents(session, onProgress) {
1773
- let runningTurn;
1774
- for await (const turn of await session.listTurns({ limit: 1 })) {
1775
- if (turn.state?.status === "running") {
1776
- runningTurn = turn;
1777
- }
1778
- }
1779
- const items = await fetchAllSessionEvents(session);
1780
- const snapshot = createEmptySessionSnapshot();
1781
- ingestSessionEventsIntoSnapshot(snapshot, items, onProgress);
1782
- if (runningTurn == null) {
1783
- return snapshot;
1784
- }
1785
- const pendingUserText = extractTurnUserText(runningTurn.input);
1786
- return replaceSessionSnapshot(snapshot, {
1787
- runningTurn,
1788
- unstable_resume: true,
1789
- groupRootBaseline: computeGroupRootBaseline(snapshot.turns),
1790
- ...pendingUserText ? {
1791
- pendingUser: {
1792
- turnId: runningTurn.id,
1793
- content: extractTurnUserMessageContent(runningTurn.input),
1794
- createdAt: new Date(runningTurn.createdAt)
1795
- }
1796
- } : {}
1797
- });
1798
- }
1799
1987
  function ingestTurnsIntoSnapshot(snapshot, turns, eventArrays) {
1800
1988
  let runningTurn;
1801
1989
  for (let i = 0; i < turns.length; i++) {
@@ -1834,9 +2022,18 @@ async function buildSnapshotFromSession(session, concurrency = DEFAULT_LIST_EVEN
1834
2022
  return replaceSessionSnapshot(snapshot, {
1835
2023
  runningTurn: turn,
1836
2024
  unstable_resume: true,
1837
- groupRootBaseline: computeGroupRootBaseline(snapshot.turns)
2025
+ groupRootBaseline: computeGroupRootBaseline(snapshot.turns),
2026
+ pendingUser: void 0
1838
2027
  });
1839
2028
  }
2029
+ async function buildSnapshotBeforeTurn(session, beforeTurnId, concurrency = DEFAULT_LIST_EVENTS_CONCURRENCY) {
2030
+ const turns = await listSessionTurnsOrdered(session);
2031
+ const beforeIndex = turns.findIndex((turn) => turn.id === beforeTurnId);
2032
+ if (beforeIndex === -1) {
2033
+ throw new Error(`Turn ${beforeTurnId} not found in session`);
2034
+ }
2035
+ return buildSnapshotBeforeTurnIndex(session, beforeIndex, concurrency, turns);
2036
+ }
1840
2037
  async function buildSnapshotBeforeTurnIndex(session, turnIndex, _concurrency = DEFAULT_LIST_EVENTS_CONCURRENCY, orderedTurns) {
1841
2038
  if (turnIndex <= 0) {
1842
2039
  return createEmptySessionSnapshot();
@@ -1859,6 +2056,11 @@ async function resolveGatewayBranchPreviousTurnId(session, turnIndex, orderedTur
1859
2056
  const turns = orderedTurns ?? await listSessionTurnsOrdered(session);
1860
2057
  return turns[turnIndex - 1]?.id ?? null;
1861
2058
  }
2059
+ async function resolveGatewayBranchPreviousTurnIdForTurn(session, turnId) {
2060
+ const turns = await listSessionTurnsOrdered(session);
2061
+ const turnIndex = turns.findIndex((turn) => turn.id === turnId);
2062
+ return resolveGatewayBranchPreviousTurnId(session, turnIndex, turns);
2063
+ }
1862
2064
  async function listSessionTurnsOrdered(session) {
1863
2065
  const turns = [];
1864
2066
  for await (const turn of await session.listTurns()) {
@@ -2073,1199 +2275,187 @@ async function* streamTurnEvents(stream, foldState, groupRootBaseline) {
2073
2275
  toolApprovalMessageCustom(
2074
2276
  approvalThreadId === ROOT_THREAD_ID ? ROOT_THREAD_ID : approvalThreadId
2075
2277
  )
2076
- );
2077
- }
2078
- if (responseThreadId != null) {
2079
- Object.assign(
2080
- custom,
2081
- toolResponseMessageCustom(
2082
- responseThreadId === ROOT_THREAD_ID ? ROOT_THREAD_ID : responseThreadId
2083
- )
2084
- );
2085
- }
2086
- const ids = groupRootBaseline != null ? rootModelMessageIdsSinceBaseline(foldState, groupRootBaseline) : foldState.threads.get(ROOT_THREAD_ID)?.modelMessageIds ?? [];
2087
- yield withSandbox({
2088
- content: buildRootAssistantContentForIds(foldState, ids),
2089
- status: approvalThreadId != null ? toolApprovalStatus() : toolResponseStatus(),
2090
- metadata: { custom }
2091
- });
2092
- return;
2093
- }
2094
- if (sandboxId != null && !sandboxIdYielded) {
2095
- const ids = groupRootBaseline != null ? rootModelMessageIdsSinceBaseline(foldState, groupRootBaseline) : foldState.threads.get(ROOT_THREAD_ID)?.modelMessageIds ?? [];
2096
- yield withSandbox({ content: buildRootAssistantContentForIds(foldState, ids) });
2097
- }
2098
- }
2099
- function turnStreamUpdateToAssistantMessage(turnId, update, existing, options) {
2100
- const id = existing?.role === "assistant" ? existing.id : `${turnId}-assistant`;
2101
- const fallbackCreatedAt = existing?.createdAt ?? /* @__PURE__ */ new Date();
2102
- return {
2103
- id,
2104
- role: "assistant",
2105
- content: update.content,
2106
- status: update.status ?? { type: "running" },
2107
- createdAt: resolveCreatedAt(id, fallbackCreatedAt, options),
2108
- metadata: {
2109
- unstable_state: null,
2110
- unstable_annotations: [],
2111
- unstable_data: [],
2112
- steps: [],
2113
- custom: update.metadata?.custom ?? {}
2114
- }
2115
- };
2116
- }
2117
- function repositoryItemsFromMessages(messages) {
2118
- const items = [];
2119
- let parentId = null;
2120
- for (const message of messages) {
2121
- items.push({ parentId, message });
2122
- parentId = message.id;
2123
- }
2124
- return items;
2125
- }
2126
-
2127
- // src/private/draftSessionBridge.ts
2128
- function createDraftSessionBridge(gateway) {
2129
- async function getDraft(draftSessionId) {
2130
- const response = await gateway.agents.private.draftSessions.get(draftSessionId);
2131
- return response.data;
2132
- }
2133
- return {
2134
- async getDraftAgentSpec(draftSessionId) {
2135
- const draft = await getDraft(draftSessionId);
2136
- return draft.agentSpec;
2137
- },
2138
- async syncAgentSpec(draftSessionId, agentSpec) {
2139
- await gateway.agents.private.draftSessions.update(draftSessionId, { agentSpec });
2140
- }
2141
- };
2142
- }
2143
-
2144
- // src/private/agentSpec.ts
2145
- function mergeAgentSpec(base, update) {
2146
- const { model: modelUpdate, ...rest } = update;
2147
- const next = {
2148
- ...base,
2149
- ...rest
2150
- };
2151
- if (modelUpdate != null) {
2152
- next.model = {
2153
- ...base.model,
2154
- ...modelUpdate,
2155
- name: modelUpdate.name ?? base.model.name,
2156
- params: modelUpdate.params != null ? { ...base.model.params, ...modelUpdate.params } : base.model.params
2157
- };
2158
- }
2159
- return next;
2160
- }
2161
- function draftSessionTitle(draft) {
2162
- return draft.title ?? draft.agentSpec.model.name;
2163
- }
2164
-
2165
- // src/sessionListStartTimestamp.ts
2166
- function sessionListStartTimestamp() {
2167
- const start = /* @__PURE__ */ new Date();
2168
- start.setFullYear(start.getFullYear() - 1);
2169
- return start.toISOString();
2170
- }
2171
-
2172
- // src/private/truefoundryDraftThreadListAdapter.ts
2173
- var THREAD_LIST_PAGE_SIZE = 20;
2174
- function createTrueFoundryDraftThreadListAdapter(options) {
2175
- const { gateway, defaultAgentSpec, getAgentSpec } = options;
2176
- return {
2177
- async list({ after } = {}) {
2178
- const page = await gateway.agents.private.draftSessions.list({
2179
- limit: THREAD_LIST_PAGE_SIZE,
2180
- pageToken: after,
2181
- startTimestamp: sessionListStartTimestamp()
2182
- });
2183
- const threads = page.data.map((draft) => ({
2184
- status: "regular",
2185
- remoteId: draft.id,
2186
- title: draftSessionTitle(draft),
2187
- lastMessageAt: new Date(draft.updatedAt)
2188
- }));
2189
- return {
2190
- threads,
2191
- nextCursor: page.response.pagination.nextPageToken ?? void 0
2192
- };
2193
- },
2194
- async initialize(_threadId) {
2195
- const response = await gateway.agents.private.draftSessions.create({
2196
- agentSpec: getAgentSpec?.() ?? defaultAgentSpec
2197
- });
2198
- const draft = response.data;
2199
- return { remoteId: draft.id, externalId: void 0 };
2200
- },
2201
- async fetch(remoteId) {
2202
- const response = await gateway.agents.private.draftSessions.get(remoteId);
2203
- const draft = response.data;
2204
- return {
2205
- status: "regular",
2206
- remoteId: draft.id,
2207
- title: draftSessionTitle(draft),
2208
- lastMessageAt: new Date(draft.updatedAt)
2209
- };
2210
- },
2211
- async rename() {
2212
- },
2213
- async archive() {
2214
- },
2215
- async unarchive() {
2216
- },
2217
- async delete() {
2218
- },
2219
- async generateTitle() {
2220
- return new ReadableStream();
2221
- }
2222
- };
2223
- }
2224
-
2225
- // src/truefoundryExtras.ts
2226
- import { createRuntimeExtras } from "@assistant-ui/core/internal";
2227
- var trueFoundryExtras = createRuntimeExtras(
2228
- "useTrueFoundryAgentRuntime"
2229
- );
2230
- var EMPTY_DRAFT_EXTRAS = {
2231
- agentSpec: null,
2232
- draftSessionId: void 0,
2233
- isSpecSyncing: false,
2234
- specError: null,
2235
- updateAgentSpec: () => {
2236
- throw new Error("Draft agent extras are only available in draft mode.");
2237
- }
2238
- };
2239
-
2240
- // ../../node_modules/.pnpm/truefoundry-gateway-sdk@0.3.1/node_modules/truefoundry-gateway-sdk/dist/esm/core/fetcher/HttpResponsePromise.mjs
2241
- var __awaiter = function(thisArg, _arguments, P, generator) {
2242
- function adopt(value) {
2243
- return value instanceof P ? value : new P(function(resolve) {
2244
- resolve(value);
2245
- });
2246
- }
2247
- return new (P || (P = Promise))(function(resolve, reject) {
2248
- function fulfilled(value) {
2249
- try {
2250
- step(generator.next(value));
2251
- } catch (e) {
2252
- reject(e);
2253
- }
2254
- }
2255
- function rejected(value) {
2256
- try {
2257
- step(generator["throw"](value));
2258
- } catch (e) {
2259
- reject(e);
2260
- }
2261
- }
2262
- function step(result) {
2263
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
2264
- }
2265
- step((generator = generator.apply(thisArg, _arguments || [])).next());
2266
- });
2267
- };
2268
- var HttpResponsePromise = class _HttpResponsePromise extends Promise {
2269
- constructor(promise) {
2270
- super((resolve) => {
2271
- resolve(void 0);
2272
- });
2273
- this.innerPromise = promise;
2274
- }
2275
- /**
2276
- * Creates an `HttpResponsePromise` from a function that returns a promise.
2277
- *
2278
- * @param fn - A function that returns a promise resolving to a `WithRawResponse` object.
2279
- * @param args - Arguments to pass to the function.
2280
- * @returns An `HttpResponsePromise` instance.
2281
- */
2282
- static fromFunction(fn, ...args) {
2283
- return new _HttpResponsePromise(fn(...args));
2284
- }
2285
- /**
2286
- * Creates a function that returns an `HttpResponsePromise` from a function that returns a promise.
2287
- *
2288
- * @param fn - A function that returns a promise resolving to a `WithRawResponse` object.
2289
- * @returns A function that returns an `HttpResponsePromise` instance.
2290
- */
2291
- static interceptFunction(fn) {
2292
- return (...args) => {
2293
- return _HttpResponsePromise.fromPromise(fn(...args));
2294
- };
2295
- }
2296
- /**
2297
- * Creates an `HttpResponsePromise` from an existing promise.
2298
- *
2299
- * @param promise - A promise resolving to a `WithRawResponse` object.
2300
- * @returns An `HttpResponsePromise` instance.
2301
- */
2302
- static fromPromise(promise) {
2303
- return new _HttpResponsePromise(promise);
2304
- }
2305
- /**
2306
- * Creates an `HttpResponsePromise` from an executor function.
2307
- *
2308
- * @param executor - A function that takes resolve and reject callbacks to create a promise.
2309
- * @returns An `HttpResponsePromise` instance.
2310
- */
2311
- static fromExecutor(executor) {
2312
- const promise = new Promise(executor);
2313
- return new _HttpResponsePromise(promise);
2314
- }
2315
- /**
2316
- * Creates an `HttpResponsePromise` from a resolved result.
2317
- *
2318
- * @param result - A `WithRawResponse` object to resolve immediately.
2319
- * @returns An `HttpResponsePromise` instance.
2320
- */
2321
- static fromResult(result) {
2322
- const promise = Promise.resolve(result);
2323
- return new _HttpResponsePromise(promise);
2324
- }
2325
- unwrap() {
2326
- if (!this.unwrappedPromise) {
2327
- this.unwrappedPromise = this.innerPromise.then(({ data }) => data);
2328
- }
2329
- return this.unwrappedPromise;
2330
- }
2331
- /** @inheritdoc */
2332
- then(onfulfilled, onrejected) {
2333
- return this.unwrap().then(onfulfilled, onrejected);
2334
- }
2335
- /** @inheritdoc */
2336
- catch(onrejected) {
2337
- return this.unwrap().catch(onrejected);
2338
- }
2339
- /** @inheritdoc */
2340
- finally(onfinally) {
2341
- return this.unwrap().finally(onfinally);
2342
- }
2343
- /**
2344
- * Retrieves the data and raw response.
2345
- *
2346
- * @returns A promise resolving to a `WithRawResponse` object.
2347
- */
2348
- withRawResponse() {
2349
- return __awaiter(this, void 0, void 0, function* () {
2350
- return yield this.innerPromise;
2351
- });
2352
- }
2353
- };
2354
-
2355
- // ../../node_modules/.pnpm/truefoundry-gateway-sdk@0.3.1/node_modules/truefoundry-gateway-sdk/dist/esm/core/pagination/Page.mjs
2356
- var __awaiter2 = function(thisArg, _arguments, P, generator) {
2357
- function adopt(value) {
2358
- return value instanceof P ? value : new P(function(resolve) {
2359
- resolve(value);
2360
- });
2361
- }
2362
- return new (P || (P = Promise))(function(resolve, reject) {
2363
- function fulfilled(value) {
2364
- try {
2365
- step(generator.next(value));
2366
- } catch (e) {
2367
- reject(e);
2368
- }
2369
- }
2370
- function rejected(value) {
2371
- try {
2372
- step(generator["throw"](value));
2373
- } catch (e) {
2374
- reject(e);
2375
- }
2376
- }
2377
- function step(result) {
2378
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
2379
- }
2380
- step((generator = generator.apply(thisArg, _arguments || [])).next());
2381
- });
2382
- };
2383
- var __await = function(v) {
2384
- return this instanceof __await ? (this.v = v, this) : new __await(v);
2385
- };
2386
- var __asyncGenerator = function(thisArg, _arguments, generator) {
2387
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
2388
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
2389
- return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function() {
2390
- return this;
2391
- }, i;
2392
- function awaitReturn(f) {
2393
- return function(v) {
2394
- return Promise.resolve(v).then(f, reject);
2395
- };
2396
- }
2397
- function verb(n, f) {
2398
- if (g[n]) {
2399
- i[n] = function(v) {
2400
- return new Promise(function(a, b) {
2401
- q.push([n, v, a, b]) > 1 || resume(n, v);
2402
- });
2403
- };
2404
- if (f) i[n] = f(i[n]);
2405
- }
2406
- }
2407
- function resume(n, v) {
2408
- try {
2409
- step(g[n](v));
2410
- } catch (e) {
2411
- settle(q[0][3], e);
2412
- }
2413
- }
2414
- function step(r) {
2415
- r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
2416
- }
2417
- function fulfill(value) {
2418
- resume("next", value);
2419
- }
2420
- function reject(value) {
2421
- resume("throw", value);
2422
- }
2423
- function settle(f, v) {
2424
- if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]);
2425
- }
2426
- };
2427
- var __asyncValues = function(o) {
2428
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
2429
- var m = o[Symbol.asyncIterator], i;
2430
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
2431
- return this;
2432
- }, i);
2433
- function verb(n) {
2434
- i[n] = o[n] && function(v) {
2435
- return new Promise(function(resolve, reject) {
2436
- v = o[n](v), settle(resolve, reject, v.done, v.value);
2437
- });
2438
- };
2439
- }
2440
- function settle(resolve, reject, d, v) {
2441
- Promise.resolve(v).then(function(v2) {
2442
- resolve({ value: v2, done: d });
2443
- }, reject);
2444
- }
2445
- };
2446
- var Page = class {
2447
- constructor({ response, rawResponse, hasNextPage, getItems, loadPage }) {
2448
- this.response = response;
2449
- this.rawResponse = rawResponse;
2450
- this.data = getItems(response);
2451
- this._hasNextPage = hasNextPage;
2452
- this.getItems = getItems;
2453
- this.loadNextPage = loadPage;
2454
- }
2455
- /**
2456
- * Retrieves the next page
2457
- * @returns this
2458
- */
2459
- getNextPage() {
2460
- return __awaiter2(this, void 0, void 0, function* () {
2461
- const { data, rawResponse } = yield this.loadNextPage(this.response).withRawResponse();
2462
- this.response = data;
2463
- this.rawResponse = rawResponse;
2464
- this.data = this.getItems(this.response);
2465
- return this;
2466
- });
2467
- }
2468
- /**
2469
- * @returns whether there is a next page to load
2470
- */
2471
- hasNextPage() {
2472
- return this._hasNextPage(this.response);
2473
- }
2474
- iterMessages() {
2475
- return __asyncGenerator(this, arguments, function* iterMessages_1() {
2476
- for (const item of this.data) {
2477
- yield yield __await(item);
2478
- }
2479
- while (this.hasNextPage()) {
2480
- yield __await(this.getNextPage());
2481
- for (const item of this.data) {
2482
- yield yield __await(item);
2483
- }
2484
- }
2485
- });
2486
- }
2487
- [Symbol.asyncIterator]() {
2488
- return __asyncGenerator(this, arguments, function* _a() {
2489
- var _b, e_1, _c, _d;
2490
- try {
2491
- for (var _e = true, _f = __asyncValues(this.iterMessages()), _g; _g = yield __await(_f.next()), _b = _g.done, !_b; _e = true) {
2492
- _d = _g.value;
2493
- _e = false;
2494
- const message = _d;
2495
- yield yield __await(message);
2496
- }
2497
- } catch (e_1_1) {
2498
- e_1 = { error: e_1_1 };
2499
- } finally {
2500
- try {
2501
- if (!_e && !_b && (_c = _f.return)) yield __await(_c.call(_f));
2502
- } finally {
2503
- if (e_1) throw e_1.error;
2504
- }
2505
- }
2506
- });
2507
- }
2508
- };
2509
-
2510
- // ../../node_modules/.pnpm/truefoundry-gateway-sdk@0.3.1/node_modules/truefoundry-gateway-sdk/dist/esm/agents/TurnStreamData.mjs
2511
- function parseSequenceNumber(id) {
2512
- if (!id) {
2513
- throw new Error("Missing SSE sequence number id.");
2514
- }
2515
- const parsed = Number(id);
2516
- if (!Number.isFinite(parsed)) {
2517
- throw new Error(`Invalid SSE sequence number id: "${id}".`);
2518
- }
2519
- return parsed;
2520
- }
2521
-
2522
- // ../../node_modules/.pnpm/truefoundry-gateway-sdk@0.3.1/node_modules/truefoundry-gateway-sdk/dist/esm/agents/Turn.mjs
2523
- var __awaiter3 = function(thisArg, _arguments, P, generator) {
2524
- function adopt(value) {
2525
- return value instanceof P ? value : new P(function(resolve) {
2526
- resolve(value);
2527
- });
2528
- }
2529
- return new (P || (P = Promise))(function(resolve, reject) {
2530
- function fulfilled(value) {
2531
- try {
2532
- step(generator.next(value));
2533
- } catch (e) {
2534
- reject(e);
2535
- }
2536
- }
2537
- function rejected(value) {
2538
- try {
2539
- step(generator["throw"](value));
2540
- } catch (e) {
2541
- reject(e);
2542
- }
2543
- }
2544
- function step(result) {
2545
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
2546
- }
2547
- step((generator = generator.apply(thisArg, _arguments || [])).next());
2548
- });
2549
- };
2550
- var __classPrivateFieldSet = function(receiver, state, value, kind, f) {
2551
- if (kind === "m") throw new TypeError("Private method is not writable");
2552
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
2553
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
2554
- return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
2555
- };
2556
- var __classPrivateFieldGet = function(receiver, state, kind, f) {
2557
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
2558
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
2559
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
2560
- };
2561
- var __await2 = function(v) {
2562
- return this instanceof __await2 ? (this.v = v, this) : new __await2(v);
2563
- };
2564
- var __asyncValues2 = function(o) {
2565
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
2566
- var m = o[Symbol.asyncIterator], i;
2567
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
2568
- return this;
2569
- }, i);
2570
- function verb(n) {
2571
- i[n] = o[n] && function(v) {
2572
- return new Promise(function(resolve, reject) {
2573
- v = o[n](v), settle(resolve, reject, v.done, v.value);
2574
- });
2575
- };
2576
- }
2577
- function settle(resolve, reject, d, v) {
2578
- Promise.resolve(v).then(function(v2) {
2579
- resolve({ value: v2, done: d });
2580
- }, reject);
2581
- }
2582
- };
2583
- var __asyncGenerator2 = function(thisArg, _arguments, generator) {
2584
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
2585
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
2586
- return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function() {
2587
- return this;
2588
- }, i;
2589
- function awaitReturn(f) {
2590
- return function(v) {
2591
- return Promise.resolve(v).then(f, reject);
2592
- };
2593
- }
2594
- function verb(n, f) {
2595
- if (g[n]) {
2596
- i[n] = function(v) {
2597
- return new Promise(function(a, b) {
2598
- q.push([n, v, a, b]) > 1 || resume(n, v);
2599
- });
2600
- };
2601
- if (f) i[n] = f(i[n]);
2602
- }
2603
- }
2604
- function resume(n, v) {
2605
- try {
2606
- step(g[n](v));
2607
- } catch (e) {
2608
- settle(q[0][3], e);
2609
- }
2610
- }
2611
- function step(r) {
2612
- r.value instanceof __await2 ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
2613
- }
2614
- function fulfill(value) {
2615
- resume("next", value);
2616
- }
2617
- function reject(value) {
2618
- resume("throw", value);
2619
- }
2620
- function settle(f, v) {
2621
- if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]);
2622
- }
2623
- };
2624
- var _Turn_instances;
2625
- var _Turn_client;
2626
- var _Turn_state;
2627
- var _Turn_applyEvent;
2628
- var DEFAULT_POLL_INTERVAL_MS = 3e3;
2629
- var MIN_POLL_INTERVAL_MS = 3e3;
2630
- var Turn = class {
2631
- constructor(turn, session, client) {
2632
- _Turn_instances.add(this);
2633
- _Turn_client.set(this, void 0);
2634
- _Turn_state.set(this, void 0);
2635
- this.id = turn.id;
2636
- this.sessionId = turn.sessionId;
2637
- this.previousTurnId = turn.previousTurnId;
2638
- this.input = turn.input;
2639
- this.createdBySubject = turn.createdBySubject;
2640
- this.createdAt = turn.createdAt;
2641
- __classPrivateFieldSet(this, _Turn_state, turn.state, "f");
2642
- this.session = session;
2643
- __classPrivateFieldSet(this, _Turn_client, client, "f");
2644
- }
2645
- /**
2646
- * @returns {TrueFoundryGatewayApi.TurnState} Updated by `refresh()`, `stream()`, and `waitForCompletion()`.
2647
- */
2648
- get state() {
2649
- return __classPrivateFieldGet(this, _Turn_state, "f");
2650
- }
2651
- // Terminal states are listed explicitly (not `status !== "running"`) so a newly added
2652
- // non-terminal status keeps polling by default; new terminal states must be added here.
2653
- isTerminal(state) {
2654
- switch (state.status) {
2655
- case "done":
2656
- case "cancelled":
2657
- case "error":
2658
- return true;
2659
- default:
2660
- return false;
2661
- }
2662
- }
2663
- // Refetch from the server, update #state in place, and return self.
2664
- /**
2665
- * Refetch from the server, update state in-place and return self.
2666
- *
2667
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
2668
- * @returns {this} This turn with updated state.
2669
- */
2670
- refresh(requestOptions) {
2671
- return __awaiter3(this, void 0, void 0, function* () {
2672
- const response = yield __classPrivateFieldGet(this, _Turn_client, "f").agents.sessions.getTurn(this.sessionId, this.id, requestOptions);
2673
- __classPrivateFieldSet(this, _Turn_state, response.data.state, "f");
2674
- return this;
2675
- });
2676
- }
2677
- /**
2678
- * Poll getTurn until terminal.
2679
- *
2680
- * @param opts.pollIntervalMs - Poll interval ms while waiting. Minimum 3000.
2681
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
2682
- * @returns {TrueFoundryGatewayApi.TurnState} Terminal turn state.
2683
- */
2684
- waitForCompletion(opts, requestOptions) {
2685
- return __awaiter3(this, void 0, void 0, function* () {
2686
- var _a;
2687
- const pollIntervalMs = (_a = opts === null || opts === void 0 ? void 0 : opts.pollIntervalMs) !== null && _a !== void 0 ? _a : DEFAULT_POLL_INTERVAL_MS;
2688
- if (pollIntervalMs < MIN_POLL_INTERVAL_MS) {
2689
- throw new Error(`pollIntervalMs must be at least ${MIN_POLL_INTERVAL_MS}ms`);
2690
- }
2691
- while (!this.isTerminal(__classPrivateFieldGet(this, _Turn_state, "f"))) {
2692
- yield new Promise((r) => setTimeout(r, pollIntervalMs));
2693
- yield this.refresh(requestOptions);
2694
- }
2695
- return __classPrivateFieldGet(this, _Turn_state, "f");
2696
- });
2697
- }
2698
- // Reconnect to the turn's SSE; let the server decide what to stream (no client-side guard).
2699
- // Updates #state in place from any event that carries a state snapshot.
2700
- /**
2701
- * Reconnect to the turn's SSE. Updates state in-place from lifecycle events.
2702
- *
2703
- * @param opts.afterSequenceNumber - Sequence number to resume SSE subscription after.
2704
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
2705
- * @yields {TurnStreamData} SSE stream items.
2706
- */
2707
- stream(opts, requestOptions) {
2708
- return __asyncGenerator2(this, arguments, function* stream_1() {
2709
- var _a, e_1, _b, _c;
2710
- const sse = yield __await2(__classPrivateFieldGet(this, _Turn_client, "f").agents.sessions.subscribeToTurn(this.sessionId, this.id, { afterSequenceNumber: opts === null || opts === void 0 ? void 0 : opts.afterSequenceNumber }, requestOptions));
2711
- try {
2712
- for (var _d = true, _e = __asyncValues2(sse.withMetadata()), _f; _f = yield __await2(_e.next()), _a = _f.done, !_a; _d = true) {
2713
- _c = _f.value;
2714
- _d = false;
2715
- const { data: event, id } = _c;
2716
- __classPrivateFieldGet(this, _Turn_instances, "m", _Turn_applyEvent).call(this, event);
2717
- yield yield __await2({ sequenceNumber: parseSequenceNumber(id), event });
2718
- }
2719
- } catch (e_1_1) {
2720
- e_1 = { error: e_1_1 };
2721
- } finally {
2722
- try {
2723
- if (!_d && !_a && (_b = _e.return)) yield __await2(_b.call(_e));
2724
- } finally {
2725
- if (e_1) throw e_1.error;
2726
- }
2727
- }
2728
- });
2729
- }
2730
- /**
2731
- * Cancel the running last turn for the session.
2732
- *
2733
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
2734
- * @returns {void}
2735
- */
2736
- cancel(requestOptions) {
2737
- return __awaiter3(this, void 0, void 0, function* () {
2738
- yield __classPrivateFieldGet(this, _Turn_client, "f").agents.sessions.cancel(this.sessionId, {}, requestOptions);
2739
- });
2740
- }
2741
- // Expose the autogen Fern Page as-is (it is already async-iterable); no re-wrapping.
2742
- /**
2743
- * Paginated turn events; use `stream()` for live SSE.
2744
- *
2745
- * @param opts.pageToken - Token from the previous response nextPageToken.
2746
- * @param opts.limit - Page size. Default 25.
2747
- * @param opts.order - Sort by creation time. Default `asc`.
2748
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
2749
- * @returns {Promise<core.Page<TrueFoundryGatewayApi.TurnEvent, TrueFoundryGatewayApi.ListEventsResponse>>} Paginated turn events.
2750
- */
2751
- listEvents(opts, requestOptions) {
2752
- return __classPrivateFieldGet(this, _Turn_client, "f").agents.sessions.listTurnEvents(this.sessionId, this.id, opts, requestOptions);
2753
- }
2754
- };
2755
- _Turn_client = /* @__PURE__ */ new WeakMap(), _Turn_state = /* @__PURE__ */ new WeakMap(), _Turn_instances = /* @__PURE__ */ new WeakSet(), _Turn_applyEvent = function _Turn_applyEvent2(event) {
2756
- if (event.type === "turn.created" || event.type === "turn.done")
2757
- __classPrivateFieldSet(this, _Turn_state, event.state, "f");
2758
- };
2759
-
2760
- // ../../node_modules/.pnpm/truefoundry-gateway-sdk@0.3.1/node_modules/truefoundry-gateway-sdk/dist/esm/agents/PreparedTurn.mjs
2761
- var __awaiter4 = function(thisArg, _arguments, P, generator) {
2762
- function adopt(value) {
2763
- return value instanceof P ? value : new P(function(resolve) {
2764
- resolve(value);
2765
- });
2766
- }
2767
- return new (P || (P = Promise))(function(resolve, reject) {
2768
- function fulfilled(value) {
2769
- try {
2770
- step(generator.next(value));
2771
- } catch (e) {
2772
- reject(e);
2773
- }
2774
- }
2775
- function rejected(value) {
2776
- try {
2777
- step(generator["throw"](value));
2778
- } catch (e) {
2779
- reject(e);
2780
- }
2781
- }
2782
- function step(result) {
2783
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
2784
- }
2785
- step((generator = generator.apply(thisArg, _arguments || [])).next());
2786
- });
2787
- };
2788
- var __classPrivateFieldSet2 = function(receiver, state, value, kind, f) {
2789
- if (kind === "m") throw new TypeError("Private method is not writable");
2790
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
2791
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
2792
- return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
2793
- };
2794
- var __classPrivateFieldGet2 = function(receiver, state, kind, f) {
2795
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
2796
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
2797
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
2798
- };
2799
- var __asyncValues3 = function(o) {
2800
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
2801
- var m = o[Symbol.asyncIterator], i;
2802
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
2803
- return this;
2804
- }, i);
2805
- function verb(n) {
2806
- i[n] = o[n] && function(v) {
2807
- return new Promise(function(resolve, reject) {
2808
- v = o[n](v), settle(resolve, reject, v.done, v.value);
2809
- });
2810
- };
2811
- }
2812
- function settle(resolve, reject, d, v) {
2813
- Promise.resolve(v).then(function(v2) {
2814
- resolve({ value: v2, done: d });
2815
- }, reject);
2816
- }
2817
- };
2818
- var __await3 = function(v) {
2819
- return this instanceof __await3 ? (this.v = v, this) : new __await3(v);
2820
- };
2821
- var __asyncDelegator = function(o) {
2822
- var i, p;
2823
- return i = {}, verb("next"), verb("throw", function(e) {
2824
- throw e;
2825
- }), verb("return"), i[Symbol.iterator] = function() {
2826
- return this;
2827
- }, i;
2828
- function verb(n, f) {
2829
- i[n] = o[n] ? function(v) {
2830
- return (p = !p) ? { value: __await3(o[n](v)), done: false } : f ? f(v) : v;
2831
- } : f;
2832
- }
2833
- };
2834
- var __asyncGenerator3 = function(thisArg, _arguments, generator) {
2835
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
2836
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
2837
- return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function() {
2838
- return this;
2839
- }, i;
2840
- function awaitReturn(f) {
2841
- return function(v) {
2842
- return Promise.resolve(v).then(f, reject);
2843
- };
2844
- }
2845
- function verb(n, f) {
2846
- if (g[n]) {
2847
- i[n] = function(v) {
2848
- return new Promise(function(a, b) {
2849
- q.push([n, v, a, b]) > 1 || resume(n, v);
2850
- });
2851
- };
2852
- if (f) i[n] = f(i[n]);
2853
- }
2854
- }
2855
- function resume(n, v) {
2856
- try {
2857
- step(g[n](v));
2858
- } catch (e) {
2859
- settle(q[0][3], e);
2860
- }
2861
- }
2862
- function step(r) {
2863
- r.value instanceof __await3 ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
2864
- }
2865
- function fulfill(value) {
2866
- resume("next", value);
2867
- }
2868
- function reject(value) {
2869
- resume("throw", value);
2870
- }
2871
- function settle(f, v) {
2872
- if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]);
2873
- }
2874
- };
2875
- var _PreparedTurn_client;
2876
- var _PreparedTurn_input;
2877
- var _PreparedTurn_previousTurnIdInput;
2878
- var _PreparedTurn_start;
2879
- var _PreparedTurn_turn;
2880
- var PreparedTurn = class {
2881
- constructor(init, session, client) {
2882
- _PreparedTurn_client.set(this, void 0);
2883
- _PreparedTurn_input.set(this, void 0);
2884
- _PreparedTurn_previousTurnIdInput.set(this, void 0);
2885
- _PreparedTurn_start.set(this, void 0);
2886
- _PreparedTurn_turn.set(this, void 0);
2887
- this.session = session;
2888
- this.sessionId = session.id;
2889
- __classPrivateFieldSet2(this, _PreparedTurn_client, client, "f");
2890
- __classPrivateFieldSet2(this, _PreparedTurn_input, init.input, "f");
2891
- __classPrivateFieldSet2(this, _PreparedTurn_previousTurnIdInput, init.previousTurnId, "f");
2892
- }
2893
- // Remaining data getters delegate to the inner Turn (undefined until started).
2894
- /**
2895
- * @returns {string | undefined} Undefined until `execute()` starts the turn.
2896
- */
2897
- get id() {
2898
- var _a;
2899
- return (_a = __classPrivateFieldGet2(this, _PreparedTurn_turn, "f")) === null || _a === void 0 ? void 0 : _a.id;
2900
- }
2901
- /**
2902
- * @returns {string | undefined} Undefined until `execute()` starts the turn.
2903
- */
2904
- get previousTurnId() {
2905
- var _a;
2906
- return (_a = __classPrivateFieldGet2(this, _PreparedTurn_turn, "f")) === null || _a === void 0 ? void 0 : _a.previousTurnId;
2907
- }
2908
- /**
2909
- * @returns {TrueFoundryGatewayApi.TurnState | undefined} Undefined until `execute()` starts the turn.
2910
- */
2911
- get state() {
2912
- var _a;
2913
- return (_a = __classPrivateFieldGet2(this, _PreparedTurn_turn, "f")) === null || _a === void 0 ? void 0 : _a.state;
2914
- }
2915
- /**
2916
- * @returns {TrueFoundryGatewayApi.Subject | undefined} Undefined until `execute()` starts the turn.
2917
- */
2918
- get createdBySubject() {
2919
- var _a;
2920
- return (_a = __classPrivateFieldGet2(this, _PreparedTurn_turn, "f")) === null || _a === void 0 ? void 0 : _a.createdBySubject;
2921
- }
2922
- /**
2923
- * @returns {string | undefined} Undefined until `execute()` starts the turn.
2924
- */
2925
- get createdAt() {
2926
- var _a;
2927
- return (_a = __classPrivateFieldGet2(this, _PreparedTurn_turn, "f")) === null || _a === void 0 ? void 0 : _a.createdAt;
2928
- }
2929
- /**
2930
- * @returns {TrueFoundryGatewayApi.TurnInputItem[] | undefined} Staged input before execute; inner turn input after.
2931
- */
2932
- get input() {
2933
- var _a, _b;
2934
- return (_b = (_a = __classPrivateFieldGet2(this, _PreparedTurn_turn, "f")) === null || _a === void 0 ? void 0 : _a.input) !== null && _b !== void 0 ? _b : __classPrivateFieldGet2(this, _PreparedTurn_input, "f");
2935
- }
2936
- execute(opts, requestOptions) {
2937
- if (__classPrivateFieldGet2(this, _PreparedTurn_start, "f") != null)
2938
- throw new Error("Turn already started; use stream() / waitForCompletion().");
2939
- __classPrivateFieldSet2(this, _PreparedTurn_start, this.openCreateTurn(requestOptions), "f");
2940
- const { stream = true, pollIntervalMs } = opts !== null && opts !== void 0 ? opts : {};
2941
- return stream === false ? this.startAndWait(pollIntervalMs, requestOptions) : this.runStreaming();
2942
- }
2943
- // Post-execution behaviors. Each throws via mustGetTurn() until execute() has started the turn,
2944
- // then delegates to the inner Turn. stream() here is the re-subscribe path (subscribeToTurn).
2945
- /**
2946
- * Resubscribe via subscribeToTurn after `execute()`.
2947
- *
2948
- * @param opts.afterSequenceNumber - Sequence number to resume SSE subscription after.
2949
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
2950
- * @yields {TurnStreamData} SSE stream items.
2951
- */
2952
- stream(opts, requestOptions) {
2953
- return __asyncGenerator3(this, arguments, function* stream_1() {
2954
- yield __await3(yield* __asyncDelegator(__asyncValues3(this.mustGetTurn().stream(opts, requestOptions))));
2955
- });
2956
- }
2957
- /**
2958
- * Refetch from the server, update state in-place and return self.
2959
- *
2960
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
2961
- * @returns {this} This prepared turn with updated state.
2962
- */
2963
- refresh(requestOptions) {
2964
- return __awaiter4(this, void 0, void 0, function* () {
2965
- yield this.mustGetTurn().refresh(requestOptions);
2966
- return this;
2967
- });
2968
- }
2969
- /**
2970
- * Poll getTurn until terminal.
2971
- *
2972
- * @param opts.pollIntervalMs - Poll interval ms while waiting. Minimum 3000.
2973
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
2974
- * @returns {TrueFoundryGatewayApi.TurnState} Terminal turn state.
2975
- */
2976
- waitForCompletion(opts, requestOptions) {
2977
- return __awaiter4(this, void 0, void 0, function* () {
2978
- return this.mustGetTurn().waitForCompletion(opts, requestOptions);
2979
- });
2980
- }
2981
- /**
2982
- * Cancel the running last turn for the session.
2983
- *
2984
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
2985
- * @returns {void}
2986
- */
2987
- cancel(requestOptions) {
2988
- return __awaiter4(this, void 0, void 0, function* () {
2989
- return this.mustGetTurn().cancel(requestOptions);
2990
- });
2991
- }
2992
- /**
2993
- * Paginated turn events; use `stream()` for live SSE.
2994
- *
2995
- * @param opts.pageToken - Token from the previous response nextPageToken.
2996
- * @param opts.limit - Page size. Default 25.
2997
- * @param opts.order - Sort by creation time. Default `asc`.
2998
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
2999
- * @returns {Promise<core.Page<TrueFoundryGatewayApi.TurnEvent, TrueFoundryGatewayApi.ListEventsResponse>>} Paginated turn events.
3000
- */
3001
- listEvents(opts, requestOptions) {
3002
- return this.mustGetTurn().listEvents(opts, requestOptions);
3003
- }
3004
- // execute(stream:true) path: consume the already-open createTurn SSE (#start), adopting the inner Turn on turn.created.
3005
- runStreaming() {
3006
- return __asyncGenerator3(this, arguments, function* runStreaming_1() {
3007
- yield __await3(yield* __asyncDelegator(__asyncValues3(this.consumeStream(yield __await3(__classPrivateFieldGet2(this, _PreparedTurn_start, "f"))))));
3008
- });
3009
- }
3010
- // execute(stream:false) path: drive the open createTurn SSE until turn.created mints the inner Turn, then poll to terminal.
3011
- startAndWait(pollIntervalMs, requestOptions) {
3012
- return __awaiter4(this, void 0, void 0, function* () {
3013
- const turn = yield this.createTurnIfNotExist();
3014
- return turn.waitForCompletion({ pollIntervalMs }, requestOptions);
3015
- });
3016
- }
3017
- // Consume an SSE stream, adopting the inner Turn from the first turn.created and yielding all events.
3018
- // Isolated so a future reconnect wrapper can re-open the stream (subscribeToTurn) on disconnect.
3019
- // NOTE: reconnect/resume is out of current scope.
3020
- consumeStream(sse) {
3021
- return __asyncGenerator3(this, arguments, function* consumeStream_1() {
3022
- var _a, e_1, _b, _c;
3023
- try {
3024
- for (var _d = true, _e = __asyncValues3(sse.withMetadata()), _f; _f = yield __await3(_e.next()), _a = _f.done, !_a; _d = true) {
3025
- _c = _f.value;
3026
- _d = false;
3027
- const { data: event, id } = _c;
3028
- if (event.type === "turn.created" && __classPrivateFieldGet2(this, _PreparedTurn_turn, "f") == null)
3029
- this.adoptTurn(event);
3030
- else if (__classPrivateFieldGet2(this, _PreparedTurn_turn, "f") != null && event.type === "turn.done")
3031
- this.replaceTurnState(event.state);
3032
- yield yield __await3({ sequenceNumber: parseSequenceNumber(id), event });
3033
- }
3034
- } catch (e_1_1) {
3035
- e_1 = { error: e_1_1 };
3036
- } finally {
3037
- try {
3038
- if (!_d && !_a && (_b = _e.return)) yield __await3(_b.call(_e));
3039
- } finally {
3040
- if (e_1) throw e_1.error;
3041
- }
3042
- }
3043
- });
3044
- }
3045
- // Returns the inner Turn or throws if execute() has not started it yet.
3046
- mustGetTurn() {
3047
- if (__classPrivateFieldGet2(this, _PreparedTurn_turn, "f") == null) {
3048
- throw new Error("Turn not started yet; call execute() first.");
3049
- }
3050
- return __classPrivateFieldGet2(this, _PreparedTurn_turn, "f");
3051
- }
3052
- // Drive the in-flight createTurn SSE (#start) only until the first turn.created has built the inner
3053
- // Turn, then break (which closes the underlying SSE via the generator's return()). Returns the Turn.
3054
- createTurnIfNotExist() {
3055
- return __awaiter4(this, void 0, void 0, function* () {
3056
- var _a, e_2, _b, _c;
3057
- if (__classPrivateFieldGet2(this, _PreparedTurn_turn, "f") == null) {
3058
- try {
3059
- for (var _d = true, _e = __asyncValues3(this.consumeStream(yield __classPrivateFieldGet2(this, _PreparedTurn_start, "f"))), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
3060
- _c = _f.value;
3061
- _d = false;
3062
- const _event = _c;
3063
- if (__classPrivateFieldGet2(this, _PreparedTurn_turn, "f") != null)
3064
- break;
3065
- }
3066
- } catch (e_2_1) {
3067
- e_2 = { error: e_2_1 };
3068
- } finally {
3069
- try {
3070
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
3071
- } finally {
3072
- if (e_2) throw e_2.error;
3073
- }
3074
- }
3075
- }
3076
- return this.mustGetTurn();
3077
- });
3078
- }
3079
- // Open the createTurn SSE with the pending input/previousTurnId. Called synchronously by execute()
3080
- // so the POST is in flight (and #start latched) before execute returns.
3081
- openCreateTurn(requestOptions) {
3082
- return __classPrivateFieldGet2(this, _PreparedTurn_client, "f").agents.sessions.createTurn(this.sessionId, { input: __classPrivateFieldGet2(this, _PreparedTurn_input, "f"), previousTurnId: __classPrivateFieldGet2(this, _PreparedTurn_previousTurnIdInput, "f") }, requestOptions);
3083
- }
3084
- // Build the inner Turn directly from the turn.created event (no extra getTurn round trip).
3085
- // The TurnCreatedEvent member of the TurnStreamingEvent union carries everything Turn needs.
3086
- // input comes from the request we sent (this.#input), not the event.
3087
- adoptTurn(event) {
3088
- __classPrivateFieldSet2(this, _PreparedTurn_turn, new Turn({
3089
- id: event.turnId,
3090
- sessionId: this.sessionId,
3091
- previousTurnId: event.previousTurnId,
3092
- input: __classPrivateFieldGet2(this, _PreparedTurn_input, "f"),
3093
- state: event.state,
3094
- createdBySubject: event.createdBy,
3095
- createdAt: event.createdAt
3096
- }, this.session, __classPrivateFieldGet2(this, _PreparedTurn_client, "f")), "f");
3097
- }
3098
- // Replace the inner Turn with a fresh one carrying the new state. State changes are rare, so
3099
- // rebuilding via Turn's own constructor (rather than mutating it) keeps Turn the source of truth.
3100
- replaceTurnState(state) {
3101
- const turn = this.mustGetTurn();
3102
- __classPrivateFieldSet2(this, _PreparedTurn_turn, new Turn({
3103
- id: turn.id,
3104
- sessionId: turn.sessionId,
3105
- previousTurnId: turn.previousTurnId,
3106
- input: turn.input,
3107
- state,
3108
- createdBySubject: turn.createdBySubject,
3109
- createdAt: turn.createdAt
3110
- }, this.session, __classPrivateFieldGet2(this, _PreparedTurn_client, "f")), "f");
3111
- }
3112
- };
3113
- _PreparedTurn_client = /* @__PURE__ */ new WeakMap(), _PreparedTurn_input = /* @__PURE__ */ new WeakMap(), _PreparedTurn_previousTurnIdInput = /* @__PURE__ */ new WeakMap(), _PreparedTurn_start = /* @__PURE__ */ new WeakMap(), _PreparedTurn_turn = /* @__PURE__ */ new WeakMap();
3114
-
3115
- // ../../node_modules/.pnpm/truefoundry-gateway-sdk@0.3.1/node_modules/truefoundry-gateway-sdk/dist/esm/agents/AgentSession.mjs
3116
- var __awaiter5 = function(thisArg, _arguments, P, generator) {
3117
- function adopt(value) {
3118
- return value instanceof P ? value : new P(function(resolve) {
3119
- resolve(value);
3120
- });
3121
- }
3122
- return new (P || (P = Promise))(function(resolve, reject) {
3123
- function fulfilled(value) {
3124
- try {
3125
- step(generator.next(value));
3126
- } catch (e) {
3127
- reject(e);
3128
- }
3129
- }
3130
- function rejected(value) {
3131
- try {
3132
- step(generator["throw"](value));
3133
- } catch (e) {
3134
- reject(e);
3135
- }
2278
+ );
3136
2279
  }
3137
- function step(result) {
3138
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
2280
+ if (responseThreadId != null) {
2281
+ Object.assign(
2282
+ custom,
2283
+ toolResponseMessageCustom(
2284
+ responseThreadId === ROOT_THREAD_ID ? ROOT_THREAD_ID : responseThreadId
2285
+ )
2286
+ );
3139
2287
  }
3140
- step((generator = generator.apply(thisArg, _arguments || [])).next());
3141
- });
3142
- };
3143
- var __classPrivateFieldSet3 = function(receiver, state, value, kind, f) {
3144
- if (kind === "m") throw new TypeError("Private method is not writable");
3145
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
3146
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
3147
- return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
3148
- };
3149
- var __classPrivateFieldGet3 = function(receiver, state, kind, f) {
3150
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3151
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
3152
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
3153
- };
3154
- var _AgentSession_client;
3155
- var AgentSession = class {
3156
- constructor(session, client) {
3157
- _AgentSession_client.set(this, void 0);
3158
- this.id = session.id;
3159
- this.agentName = session.agentName;
3160
- this.title = session.title;
3161
- this.createdBySubject = session.createdBySubject;
3162
- this.createdAt = session.createdAt;
3163
- this.updatedAt = session.updatedAt;
3164
- __classPrivateFieldSet3(this, _AgentSession_client, client, "f");
3165
- }
3166
- /**
3167
- * Stage a turn locally; call `execute()` to start `createTurn`.
3168
- *
3169
- * @param opts.input - Turn input items passed to createTurn.
3170
- * @param opts.previousTurnId - Previous turn to chain from. Default `auto`.
3171
- * @returns {PreparedTurn} Staged turn.
3172
- */
3173
- prepareTurn(opts) {
3174
- return new PreparedTurn({ input: opts === null || opts === void 0 ? void 0 : opts.input, previousTurnId: opts === null || opts === void 0 ? void 0 : opts.previousTurnId }, this, __classPrivateFieldGet3(this, _AgentSession_client, "f"));
3175
- }
3176
- /**
3177
- * List turns in this session.
3178
- *
3179
- * @param opts.pageToken - Token from the previous response nextPageToken.
3180
- * @param opts.limit - Page size. Default 10.
3181
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
3182
- * @returns {core.Page<Turn, TrueFoundryGatewayApi.ListTurnsResponse>} Paginated turns.
3183
- */
3184
- listTurns(opts, requestOptions) {
3185
- return __awaiter5(this, void 0, void 0, function* () {
3186
- const client = __classPrivateFieldGet3(this, _AgentSession_client, "f");
3187
- const sessionId = this.id;
3188
- const page = yield client.agents.sessions.listTurns(sessionId, opts, requestOptions);
3189
- return new Page({
3190
- response: page.response,
3191
- rawResponse: page.rawResponse,
3192
- hasNextPage: (response) => !!(response === null || response === void 0 ? void 0 : response.pagination.nextPageToken),
3193
- getItems: (response) => {
3194
- var _a;
3195
- return ((_a = response === null || response === void 0 ? void 0 : response.data) !== null && _a !== void 0 ? _a : []).map((turn) => new Turn(turn, this, client));
3196
- },
3197
- loadPage: (response) => HttpResponsePromise.fromPromise(client.agents.sessions.listTurns(sessionId, Object.assign(Object.assign({}, opts), { pageToken: response === null || response === void 0 ? void 0 : response.pagination.nextPageToken }), requestOptions).then((nextPage) => ({ data: nextPage.response, rawResponse: nextPage.rawResponse })))
3198
- });
3199
- });
3200
- }
3201
- /**
3202
- * Fetch a turn by ID.
3203
- *
3204
- * @param opts.turnId - Unique identifier of the turn to fetch.
3205
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
3206
- * @returns {Turn} Turn data.
3207
- */
3208
- getTurn(opts, requestOptions) {
3209
- return __awaiter5(this, void 0, void 0, function* () {
3210
- const response = yield __classPrivateFieldGet3(this, _AgentSession_client, "f").agents.sessions.getTurn(this.id, opts.turnId, requestOptions);
3211
- return new Turn(response.data, this, __classPrivateFieldGet3(this, _AgentSession_client, "f"));
2288
+ const ids = groupRootBaseline != null ? rootModelMessageIdsSinceBaseline(foldState, groupRootBaseline) : foldState.threads.get(ROOT_THREAD_ID)?.modelMessageIds ?? [];
2289
+ yield withSandbox({
2290
+ content: buildRootAssistantContentForIds(foldState, ids),
2291
+ status: approvalThreadId != null ? toolApprovalStatus() : toolResponseStatus(),
2292
+ metadata: { custom }
3212
2293
  });
2294
+ return;
3213
2295
  }
3214
- /**
3215
- * Cancel the running last turn for the session.
3216
- *
3217
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
3218
- * @returns {void}
3219
- */
3220
- cancel(requestOptions) {
3221
- return __awaiter5(this, void 0, void 0, function* () {
3222
- yield __classPrivateFieldGet3(this, _AgentSession_client, "f").agents.sessions.cancel(this.id, {}, requestOptions);
3223
- });
2296
+ if (sandboxId != null && !sandboxIdYielded) {
2297
+ const ids = groupRootBaseline != null ? rootModelMessageIdsSinceBaseline(foldState, groupRootBaseline) : foldState.threads.get(ROOT_THREAD_ID)?.modelMessageIds ?? [];
2298
+ yield withSandbox({ content: buildRootAssistantContentForIds(foldState, ids) });
3224
2299
  }
3225
- /**
3226
- * Paginated session events across turns (newest first); subscribe to a running turn for live events.
3227
- *
3228
- * @param opts.pageToken - Token from the previous response nextPageToken.
3229
- * @param opts.lastTurnId - Newest turn in the listing window (initial load only). Omit to use the session last turn.
3230
- * @param opts.limit - Page size. Default 100.
3231
- * @param requestOptions - Overrides client timeout, retries, abortSignal, headers, queryParams.
3232
- * @returns {Promise<core.Page<TrueFoundryGatewayApi.SessionEventItem, TrueFoundryGatewayApi.ListSessionEventsResponse>>} Paginated session events.
3233
- */
3234
- listEvents(opts, requestOptions) {
3235
- return __classPrivateFieldGet3(this, _AgentSession_client, "f").agents.sessions.listEvents(this.id, opts, requestOptions);
2300
+ }
2301
+ function turnStreamUpdateToAssistantMessage(turnId, update, existing, options) {
2302
+ const id = existing?.role === "assistant" ? existing.id : `${turnId}-assistant`;
2303
+ const fallbackCreatedAt = existing?.createdAt ?? /* @__PURE__ */ new Date();
2304
+ return {
2305
+ id,
2306
+ role: "assistant",
2307
+ content: update.content,
2308
+ status: update.status ?? { type: "running" },
2309
+ createdAt: resolveCreatedAt(id, fallbackCreatedAt, options),
2310
+ metadata: {
2311
+ unstable_state: null,
2312
+ unstable_annotations: [],
2313
+ unstable_data: [],
2314
+ steps: [],
2315
+ custom: update.metadata?.custom ?? {}
2316
+ }
2317
+ };
2318
+ }
2319
+ function repositoryItemsFromMessages(messages) {
2320
+ const items = [];
2321
+ let parentId = null;
2322
+ for (const message of messages) {
2323
+ items.push({ parentId, message });
2324
+ parentId = message.id;
3236
2325
  }
3237
- };
3238
- _AgentSession_client = /* @__PURE__ */ new WeakMap();
2326
+ return items;
2327
+ }
3239
2328
 
3240
- // src/private/bindDraftAgentSession.ts
3241
- var inflightByDraftId = /* @__PURE__ */ new Map();
3242
- function getGatewayFromSessionClient(client) {
3243
- const internal = client;
2329
+ // src/private/getGatewayFromPrivateClient.ts
2330
+ function getGatewayFromPrivateClient(privateClient) {
2331
+ const internal = privateClient;
3244
2332
  if (internal.client == null) {
3245
- throw new Error("AgentSessionClient is missing an internal gateway client.");
2333
+ throw new Error("PrivateAgentSessionClient is missing an internal gateway client.");
3246
2334
  }
3247
2335
  return internal.client;
3248
2336
  }
3249
- function draftToSessionRecord(draft) {
2337
+
2338
+ // src/private/draftSessionBridge.ts
2339
+ var DRAFT_SESSION_LAST_UPDATED_AT_HEADER = "x-tfy-session-last-updated-at";
2340
+ function createDraftSessionBridge(privateClient) {
2341
+ return {
2342
+ async getDraftAgentSpec(draftSessionId) {
2343
+ const draft = await privateClient.getDraftSession({ draftSessionId });
2344
+ return draft.agentSpec;
2345
+ },
2346
+ async syncAgentSpec(draftSessionId, agentSpec) {
2347
+ const gateway = getGatewayFromPrivateClient(privateClient);
2348
+ const response = await gateway.agents.private.draftSessions.update(
2349
+ draftSessionId,
2350
+ { agentSpec }
2351
+ );
2352
+ return response.data.updatedAt;
2353
+ }
2354
+ };
2355
+ }
2356
+
2357
+ // src/private/agentSpec.ts
2358
+ function mergeAgentSpec(base, update) {
2359
+ const { model: modelUpdate, ...rest } = update;
2360
+ const next = {
2361
+ ...base,
2362
+ ...rest
2363
+ };
2364
+ if (modelUpdate != null) {
2365
+ next.model = {
2366
+ ...base.model,
2367
+ ...modelUpdate,
2368
+ name: modelUpdate.name ?? base.model.name,
2369
+ params: modelUpdate.params != null ? { ...base.model.params, ...modelUpdate.params } : base.model.params
2370
+ };
2371
+ }
2372
+ return next;
2373
+ }
2374
+ function draftSessionTitle(draft) {
2375
+ return draft.title ?? draft.agentSpec.model.name;
2376
+ }
2377
+
2378
+ // src/sessionListStartTimestamp.ts
2379
+ function sessionListStartTimestamp() {
2380
+ const start = /* @__PURE__ */ new Date();
2381
+ start.setFullYear(start.getFullYear() - 1);
2382
+ return start.toISOString();
2383
+ }
2384
+
2385
+ // src/private/truefoundryDraftThreadListAdapter.ts
2386
+ var THREAD_LIST_PAGE_SIZE = 20;
2387
+ function createTrueFoundryDraftThreadListAdapter(options) {
2388
+ const { privateClient, defaultAgentSpec, getAgentSpec } = options;
3250
2389
  return {
3251
- id: draft.id,
3252
- agentName: draft.agentName ?? "",
3253
- title: draft.title,
3254
- createdBySubject: draft.createdBySubject,
3255
- createdAt: draft.createdAt,
3256
- updatedAt: draft.updatedAt
2390
+ async list({ after } = {}) {
2391
+ const page = await privateClient.listDraftSessions({
2392
+ limit: THREAD_LIST_PAGE_SIZE,
2393
+ pageToken: after,
2394
+ startTimestamp: sessionListStartTimestamp()
2395
+ });
2396
+ const threads = page.data.map((draft) => ({
2397
+ status: "regular",
2398
+ remoteId: draft.id,
2399
+ title: draftSessionTitle(draft),
2400
+ lastMessageAt: new Date(draft.updatedAt)
2401
+ }));
2402
+ return {
2403
+ threads,
2404
+ nextCursor: page.response.pagination.nextPageToken ?? void 0
2405
+ };
2406
+ },
2407
+ async initialize(_threadId) {
2408
+ const draft = await privateClient.createDraftSession({
2409
+ agentSpec: getAgentSpec?.() ?? defaultAgentSpec
2410
+ });
2411
+ return { remoteId: draft.id, externalId: void 0 };
2412
+ },
2413
+ async fetch(remoteId) {
2414
+ const draft = await privateClient.getDraftSession({
2415
+ draftSessionId: remoteId
2416
+ });
2417
+ return {
2418
+ status: "regular",
2419
+ remoteId: draft.id,
2420
+ title: draftSessionTitle(draft),
2421
+ lastMessageAt: new Date(draft.updatedAt)
2422
+ };
2423
+ },
2424
+ async rename() {
2425
+ },
2426
+ async archive() {
2427
+ },
2428
+ async unarchive() {
2429
+ },
2430
+ async delete() {
2431
+ },
2432
+ async generateTitle() {
2433
+ return new ReadableStream();
2434
+ }
3257
2435
  };
3258
2436
  }
3259
- async function bindDraftAgentSession(client, gateway, draftSessionId) {
2437
+
2438
+ // src/truefoundryExtras.ts
2439
+ import { createRuntimeExtras } from "@assistant-ui/core/internal";
2440
+ var trueFoundryExtras = createRuntimeExtras(
2441
+ "useTrueFoundryAgentRuntime"
2442
+ );
2443
+ var EMPTY_DRAFT_EXTRAS = {
2444
+ agentSpec: null,
2445
+ draftSessionId: void 0,
2446
+ isSpecSyncing: false,
2447
+ specError: null,
2448
+ updateAgentSpec: () => {
2449
+ throw new Error("Draft agent extras are only available in draft mode.");
2450
+ }
2451
+ };
2452
+
2453
+ // src/private/bindDraftAgentSession.ts
2454
+ var inflightByDraftId = /* @__PURE__ */ new Map();
2455
+ async function bindDraftAgentSession(privateClient, draftSessionId) {
3260
2456
  let inflight = inflightByDraftId.get(draftSessionId);
3261
2457
  if (inflight == null) {
3262
- inflight = (async () => {
3263
- const response = await gateway.agents.private.draftSessions.get(draftSessionId);
3264
- return new AgentSession(
3265
- draftToSessionRecord(response.data),
3266
- getGatewayFromSessionClient(client)
3267
- );
3268
- })().finally(() => {
2458
+ inflight = privateClient.getDraftSession({ draftSessionId }).then((draft) => draft).finally(() => {
3269
2459
  if (inflightByDraftId.get(draftSessionId) === inflight) {
3270
2460
  inflightByDraftId.delete(draftSessionId);
3271
2461
  }
@@ -3278,8 +2468,8 @@ async function bindDraftAgentSession(client, gateway, draftSessionId) {
3278
2468
  // src/sessions.ts
3279
2469
  var inflightBySessionId = /* @__PURE__ */ new Map();
3280
2470
  function getSession(client, sessionId, options) {
3281
- if (options?.draftGateway != null) {
3282
- return bindDraftAgentSession(client, options.draftGateway, sessionId);
2471
+ if (options?.privateClient != null) {
2472
+ return bindDraftAgentSession(options.privateClient, sessionId);
3283
2473
  }
3284
2474
  let inflight = inflightBySessionId.get(sessionId);
3285
2475
  if (inflight == null) {
@@ -3360,15 +2550,15 @@ function resolveTrueFoundryAgentConfig(options) {
3360
2550
  }
3361
2551
  function resolveTrueFoundryAgentRuntimeOptions(options) {
3362
2552
  const agent = resolveTrueFoundryAgentConfig(options);
3363
- if (agent.mode === "draft" && options.gateway == null) {
2553
+ if (agent.mode === "draft" && options.privateClient == null) {
3364
2554
  throw new Error(
3365
- "Draft agent mode requires a `gateway` TrueFoundryGateway client."
2555
+ "Draft agent mode requires a `privateClient` PrivateAgentSessionClient."
3366
2556
  );
3367
2557
  }
3368
2558
  return {
3369
2559
  ...options,
3370
2560
  agent,
3371
- gateway: options.gateway
2561
+ privateClient: options.privateClient
3372
2562
  };
3373
2563
  }
3374
2564
 
@@ -3392,6 +2582,29 @@ function useDraftAgentSpec({
3392
2582
  const syncGenerationRef = useRef(0);
3393
2583
  const loadedDraftIdRef = useRef(void 0);
3394
2584
  const localDirtyRef = useRef(false);
2585
+ const lastUpdatedAtRef = useRef(void 0);
2586
+ const pendingFlushRef = useRef(void 0);
2587
+ const inFlightFlushRef = useRef(void 0);
2588
+ const activeDraftIdRef = useRef(draftSessionId);
2589
+ useEffect(() => {
2590
+ const previousDraftId = activeDraftIdRef.current;
2591
+ if (previousDraftId === draftSessionId) {
2592
+ return;
2593
+ }
2594
+ activeDraftIdRef.current = draftSessionId;
2595
+ syncGenerationRef.current++;
2596
+ if (syncTimeoutRef.current != null) {
2597
+ clearTimeout(syncTimeoutRef.current);
2598
+ syncTimeoutRef.current = void 0;
2599
+ }
2600
+ pendingFlushRef.current = void 0;
2601
+ inFlightFlushRef.current = void 0;
2602
+ lastUpdatedAtRef.current = void 0;
2603
+ setIsSpecSyncing(false);
2604
+ if (previousDraftId != null) {
2605
+ localDirtyRef.current = false;
2606
+ }
2607
+ }, [draftSessionId]);
3395
2608
  useEffect(() => {
3396
2609
  if (!enabled || draftBridge == null) {
3397
2610
  return;
@@ -3440,10 +2653,11 @@ function useDraftAgentSpec({
3440
2653
  }
3441
2654
  setIsSpecSyncing(true);
3442
2655
  try {
3443
- await draftBridge.syncAgentSpec(draftId, spec);
2656
+ const updatedAt = await draftBridge.syncAgentSpec(draftId, spec);
3444
2657
  if (generation !== syncGenerationRef.current) {
3445
2658
  return;
3446
2659
  }
2660
+ lastUpdatedAtRef.current = updatedAt || (/* @__PURE__ */ new Date()).toISOString();
3447
2661
  setSpecError(null);
3448
2662
  onAgentSpecChange?.(spec);
3449
2663
  } catch (error) {
@@ -3465,14 +2679,47 @@ function useDraftAgentSpec({
3465
2679
  clearTimeout(syncTimeoutRef.current);
3466
2680
  }
3467
2681
  const generation = ++syncGenerationRef.current;
2682
+ const flush = () => {
2683
+ pendingFlushRef.current = void 0;
2684
+ syncTimeoutRef.current = void 0;
2685
+ const promise = flushSpecSync(draftId, spec, generation).finally(() => {
2686
+ if (inFlightFlushRef.current === promise) {
2687
+ inFlightFlushRef.current = void 0;
2688
+ }
2689
+ });
2690
+ inFlightFlushRef.current = promise;
2691
+ return promise;
2692
+ };
2693
+ pendingFlushRef.current = flush;
3468
2694
  syncTimeoutRef.current = setTimeout(() => {
3469
- void flushSpecSync(draftId, spec, generation);
2695
+ void flush();
3470
2696
  }, SPEC_SYNC_DEBOUNCE_MS);
3471
2697
  },
3472
2698
  [flushSpecSync]
3473
2699
  );
3474
2700
  const scheduleSpecSyncRef = useRef(scheduleSpecSync);
3475
2701
  scheduleSpecSyncRef.current = scheduleSpecSync;
2702
+ const flushPendingSpecSyncNow = useCallback(async () => {
2703
+ if (syncTimeoutRef.current != null) {
2704
+ clearTimeout(syncTimeoutRef.current);
2705
+ syncTimeoutRef.current = void 0;
2706
+ }
2707
+ const pending = pendingFlushRef.current;
2708
+ if (pending != null) {
2709
+ pendingFlushRef.current = void 0;
2710
+ await pending();
2711
+ return;
2712
+ }
2713
+ if (inFlightFlushRef.current != null) {
2714
+ await inFlightFlushRef.current;
2715
+ }
2716
+ }, []);
2717
+ const takeTurnHeaderTimestamp = useCallback(async () => {
2718
+ await flushPendingSpecSyncNow();
2719
+ const updatedAt = lastUpdatedAtRef.current;
2720
+ lastUpdatedAtRef.current = void 0;
2721
+ return updatedAt;
2722
+ }, [flushPendingSpecSyncNow]);
3476
2723
  useEffect(
3477
2724
  () => () => {
3478
2725
  if (syncTimeoutRef.current != null) {
@@ -3501,7 +2748,8 @@ function useDraftAgentSpec({
3501
2748
  draftSessionId: enabled ? draftSessionId : void 0,
3502
2749
  isSpecSyncing: enabled ? isSpecSyncing : false,
3503
2750
  specError: enabled ? specError : null,
3504
- updateAgentSpec
2751
+ updateAgentSpec,
2752
+ takeTurnHeaderTimestamp
3505
2753
  }),
3506
2754
  [
3507
2755
  agentSpec,
@@ -3509,6 +2757,7 @@ function useDraftAgentSpec({
3509
2757
  enabled,
3510
2758
  isSpecSyncing,
3511
2759
  specError,
2760
+ takeTurnHeaderTimestamp,
3512
2761
  updateAgentSpec
3513
2762
  ]
3514
2763
  );
@@ -3521,7 +2770,7 @@ import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMem
3521
2770
  // src/loadSessionSnapshot.ts
3522
2771
  var inflightBySessionId2 = /* @__PURE__ */ new Map();
3523
2772
  function loadSessionSnapshot(client, sessionId, sessionOptions, onProgress) {
3524
- const cacheKey = sessionOptions?.draftGateway != null ? `draft:${sessionId}` : sessionId;
2773
+ const cacheKey = sessionOptions?.privateClient != null ? `draft:${sessionId}` : sessionId;
3525
2774
  let inflight = inflightBySessionId2.get(cacheKey);
3526
2775
  if (inflight == null) {
3527
2776
  inflight = getSession(client, sessionId, sessionOptions).then(
@@ -3593,7 +2842,13 @@ async function* streamTurnContent(session, foldState, options, abortSignal, grou
3593
2842
  }
3594
2843
  try {
3595
2844
  yield* streamTurnEvents(
3596
- turn.execute({ stream: true }, { abortSignal }),
2845
+ turn.execute(
2846
+ { stream: true },
2847
+ {
2848
+ abortSignal,
2849
+ ...options.headers != null ? { headers: options.headers } : {}
2850
+ }
2851
+ ),
3597
2852
  foldState,
3598
2853
  groupRootBaseline
3599
2854
  );
@@ -3745,16 +3000,6 @@ async function resolveActiveSessionId(remoteId, resolveConversationSessionId) {
3745
3000
  }
3746
3001
  return remoteId;
3747
3002
  }
3748
- function findTurnIndex(snapshot, turnId) {
3749
- const committedIndex = snapshot.turns.findIndex((turn) => turn.id === turnId);
3750
- if (committedIndex !== -1) {
3751
- return committedIndex;
3752
- }
3753
- if (snapshot.pendingUser?.turnId === turnId) {
3754
- return snapshot.turns.length;
3755
- }
3756
- throw new Error(`Turn ${turnId} not found in session snapshot`);
3757
- }
3758
3003
  function resolveTurnInput(snapshot, turnId) {
3759
3004
  const turnRecord = snapshot.turns.find((turn) => turn.id === turnId);
3760
3005
  if (turnRecord?.input != null) {
@@ -3773,24 +3018,29 @@ function useTrueFoundryAgentMessages({
3773
3018
  onError,
3774
3019
  initializeSession,
3775
3020
  resolveConversationSessionId,
3776
- draftGateway
3021
+ privateClient,
3022
+ getTurnHeaders
3777
3023
  }) {
3778
3024
  const sessionOptions = useMemo2(
3779
- () => draftGateway != null ? { draftGateway } : void 0,
3780
- [draftGateway]
3025
+ () => privateClient != null ? { privateClient } : void 0,
3026
+ [privateClient]
3781
3027
  );
3782
3028
  const [snapshot, setSnapshot] = useState2(createEmptySessionSnapshot);
3783
3029
  const [isRunning, setIsRunning] = useState2(false);
3784
3030
  const [isLoading, setIsLoading] = useState2(false);
3031
+ const [isLoadingOlderHistory, setIsLoadingOlderHistory] = useState2(false);
3785
3032
  const [loadRetryTrigger, setLoadRetryTrigger] = useState2(0);
3786
3033
  const snapshotRef = useRef2(snapshot);
3787
3034
  snapshotRef.current = snapshot;
3035
+ const loadOlderInflightRef = useRef2(null);
3788
3036
  const onErrorRef = useRef2(onError);
3789
3037
  onErrorRef.current = onError;
3790
3038
  const resolveConversationSessionIdRef = useRef2(resolveConversationSessionId);
3791
3039
  resolveConversationSessionIdRef.current = resolveConversationSessionId;
3792
3040
  const initializeSessionRef = useRef2(initializeSession);
3793
3041
  initializeSessionRef.current = initializeSession;
3042
+ const getTurnHeadersRef = useRef2(getTurnHeaders);
3043
+ getTurnHeadersRef.current = getTurnHeaders;
3794
3044
  const createdAtByMessageIdRef = useRef2(/* @__PURE__ */ new Map());
3795
3045
  const abortControllerRef = useRef2(null);
3796
3046
  const activeRunRef = useRef2(null);
@@ -3920,9 +3170,11 @@ function useTrueFoundryAgentMessages({
3920
3170
  const generation = ++loadGenerationRef.current;
3921
3171
  ++streamGenerationRef.current;
3922
3172
  abortControllerRef.current?.abort();
3173
+ loadOlderInflightRef.current = null;
3923
3174
  createdAtByMessageIdRef.current = /* @__PURE__ */ new Map();
3924
3175
  setSnapshot(createEmptySessionSnapshot());
3925
3176
  setIsLoading(true);
3177
+ setIsLoadingOlderHistory(false);
3926
3178
  try {
3927
3179
  const conversationSessionId = await resolveActiveSessionId(
3928
3180
  sessionId,
@@ -3990,6 +3242,8 @@ function useTrueFoundryAgentMessages({
3990
3242
  resolveConversationSessionIdRef.current
3991
3243
  );
3992
3244
  const session = await getSession(client, conversationSessionId, sessionOptions);
3245
+ const turnHeaders = await getTurnHeadersRef.current?.();
3246
+ const streamHeaders = turnHeaders != null ? { headers: turnHeaders } : {};
3993
3247
  const isContinuation = "inputs" in options || "resumeMcpAuth" in options && options.resumeMcpAuth === true;
3994
3248
  const continuationTurnId = snapshotRef.current.activeStream?.turnId;
3995
3249
  const turnId = isContinuation && continuationTurnId != null ? continuationTurnId : generateId();
@@ -4048,7 +3302,7 @@ function useTrueFoundryAgentMessages({
4048
3302
  return streamTurnContent(
4049
3303
  session,
4050
3304
  snapshotRef.current.fold,
4051
- { inputs: options.inputs },
3305
+ { inputs: options.inputs, ...streamHeaders },
4052
3306
  signal,
4053
3307
  groupRootBaseline
4054
3308
  );
@@ -4057,7 +3311,7 @@ function useTrueFoundryAgentMessages({
4057
3311
  return streamTurnContent(
4058
3312
  session,
4059
3313
  snapshotRef.current.fold,
4060
- { resumeMcpAuth: true },
3314
+ { resumeMcpAuth: true, ...streamHeaders },
4061
3315
  signal,
4062
3316
  groupRootBaseline
4063
3317
  );
@@ -4067,7 +3321,8 @@ function useTrueFoundryAgentMessages({
4067
3321
  snapshotRef.current.fold,
4068
3322
  {
4069
3323
  userMessage: options.userMessage,
4070
- ...options.previousTurnId !== void 0 ? { previousTurnId: options.previousTurnId } : {}
3324
+ ...options.previousTurnId !== void 0 ? { previousTurnId: options.previousTurnId } : {},
3325
+ ...streamHeaders
4071
3326
  },
4072
3327
  signal,
4073
3328
  groupRootBaseline
@@ -4171,20 +3426,19 @@ function useTrueFoundryAgentMessages({
4171
3426
  }
4172
3427
  const committed = commitActiveStream(snapshotRef.current);
4173
3428
  setSnapshot(committed);
4174
- const turnIndex = findTurnIndex(committed, turnId);
4175
3429
  await cancel();
4176
3430
  const conversationSessionId = await resolveActiveSessionId(
4177
3431
  activeSessionId,
4178
3432
  resolveConversationSessionIdRef.current
4179
3433
  );
4180
3434
  const session = await getSession(client, conversationSessionId, sessionOptions);
4181
- const previousTurnId = await resolveGatewayBranchPreviousTurnId(
3435
+ const previousTurnId = await resolveGatewayBranchPreviousTurnIdForTurn(
4182
3436
  session,
4183
- turnIndex
3437
+ turnId
4184
3438
  );
4185
- const rewound = await buildSnapshotBeforeTurnIndex(
3439
+ const rewound = await buildSnapshotBeforeTurn(
4186
3440
  session,
4187
- turnIndex,
3441
+ turnId,
4188
3442
  listEventsConcurrency
4189
3443
  );
4190
3444
  createdAtByMessageIdRef.current = /* @__PURE__ */ new Map();
@@ -4235,10 +3489,64 @@ function useTrueFoundryAgentMessages({
4235
3489
  const retryLoad = useCallback2(() => {
4236
3490
  setLoadRetryTrigger((n) => n + 1);
4237
3491
  }, []);
3492
+ const hasOlderHistory = snapshot.historyPagination?.hasOlder === true;
3493
+ const loadOlderHistory = useCallback2(async () => {
3494
+ if (sessionId == null || isMain === false) {
3495
+ return;
3496
+ }
3497
+ if (loadOlderInflightRef.current != null) {
3498
+ return loadOlderInflightRef.current;
3499
+ }
3500
+ const current = snapshotRef.current;
3501
+ if (current.historyPagination?.hasOlder !== true) {
3502
+ return;
3503
+ }
3504
+ if (current.historyPagination.olderPageToken == null) {
3505
+ return;
3506
+ }
3507
+ const generation = loadGenerationRef.current;
3508
+ setIsLoadingOlderHistory(true);
3509
+ const run = (async () => {
3510
+ try {
3511
+ const conversationSessionId = await resolveActiveSessionId(
3512
+ sessionId,
3513
+ resolveConversationSessionIdRef.current
3514
+ );
3515
+ const session = await getSession(
3516
+ client,
3517
+ conversationSessionId,
3518
+ sessionOptions
3519
+ );
3520
+ const next = await prependOlderSessionHistory(
3521
+ session,
3522
+ snapshotRef.current
3523
+ );
3524
+ if (generation !== loadGenerationRef.current) {
3525
+ return;
3526
+ }
3527
+ setSnapshot(next);
3528
+ } catch (error) {
3529
+ if (generation === loadGenerationRef.current) {
3530
+ onErrorRef.current?.(error);
3531
+ }
3532
+ throw error;
3533
+ } finally {
3534
+ if (generation === loadGenerationRef.current) {
3535
+ setIsLoadingOlderHistory(false);
3536
+ }
3537
+ loadOlderInflightRef.current = null;
3538
+ }
3539
+ })();
3540
+ loadOlderInflightRef.current = run;
3541
+ return run;
3542
+ }, [client, isMain, sessionId, sessionOptions]);
4238
3543
  return {
4239
3544
  messages,
4240
3545
  isRunning,
4241
3546
  isLoading,
3547
+ isLoadingOlderHistory,
3548
+ hasOlderHistory,
3549
+ loadOlderHistory,
4242
3550
  retryLoad,
4243
3551
  sendTurn,
4244
3552
  cancel,
@@ -4256,14 +3564,14 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
4256
3564
  const {
4257
3565
  client,
4258
3566
  agent,
4259
- gateway,
3567
+ privateClient,
4260
3568
  adapters,
4261
3569
  onError,
4262
3570
  listEventsConcurrency,
4263
3571
  ...sharedOptions
4264
3572
  } = options;
4265
3573
  const draftBridgeRef = useRef3(
4266
- agent.mode === "draft" && gateway != null ? createDraftSessionBridge(gateway) : null
3574
+ agent.mode === "draft" && privateClient != null ? createDraftSessionBridge(privateClient) : null
4267
3575
  );
4268
3576
  const draftSessionId = useAuiState(
4269
3577
  (state) => agent.mode === "draft" ? state.threadListItem.remoteId ?? void 0 : void 0
@@ -4279,6 +3587,18 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
4279
3587
  onAgentSpecChange: agent.mode === "draft" ? agent.onAgentSpecChange : void 0,
4280
3588
  onError
4281
3589
  });
3590
+ const takeTurnHeaderTimestampRef = useRef3(draftSpec.takeTurnHeaderTimestamp);
3591
+ takeTurnHeaderTimestampRef.current = draftSpec.takeTurnHeaderTimestamp;
3592
+ const getTurnHeaders = useCallback3(async () => {
3593
+ if (agent.mode !== "draft") {
3594
+ return void 0;
3595
+ }
3596
+ const updatedAt = await takeTurnHeaderTimestampRef.current();
3597
+ if (updatedAt == null) {
3598
+ return void 0;
3599
+ }
3600
+ return { [DRAFT_SESSION_LAST_UPDATED_AT_HEADER]: updatedAt };
3601
+ }, [agent.mode]);
4282
3602
  const aui = useAui();
4283
3603
  const initializeSession = useCallback3(
4284
3604
  () => aui.threadListItem().initialize(),
@@ -4290,6 +3610,9 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
4290
3610
  messages,
4291
3611
  isRunning,
4292
3612
  isLoading,
3613
+ isLoadingOlderHistory,
3614
+ hasOlderHistory,
3615
+ loadOlderHistory,
4293
3616
  sendTurn,
4294
3617
  cancel,
4295
3618
  respondToToolApproval,
@@ -4305,7 +3628,8 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
4305
3628
  listEventsConcurrency,
4306
3629
  onError,
4307
3630
  initializeSession,
4308
- draftGateway: agent.mode === "draft" ? gateway : void 0
3631
+ privateClient: agent.mode === "draft" ? privateClient : void 0,
3632
+ getTurnHeaders: agent.mode === "draft" ? getTurnHeaders : void 0
4309
3633
  });
4310
3634
  if (agent.mode === "draft" && draftSpec.agentSpec != null) {
4311
3635
  pendingAgentSpecRef.current = draftSpec.agentSpec;
@@ -4326,9 +3650,9 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
4326
3650
  );
4327
3651
  const downloadSandboxFile = useCallback3(
4328
3652
  async (path) => {
4329
- if (gateway == null) {
3653
+ if (privateClient == null) {
4330
3654
  const error = new Error(
4331
- "Downloading a sandbox file requires a `gateway` TrueFoundryGateway client."
3655
+ "Downloading a sandbox file requires a `privateClient` PrivateAgentSessionClient."
4332
3656
  );
4333
3657
  onError?.(error);
4334
3658
  throw error;
@@ -4338,10 +3662,11 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
4338
3662
  onError?.(error);
4339
3663
  throw error;
4340
3664
  }
3665
+ const gateway = getGatewayFromPrivateClient(privateClient);
4341
3666
  const response = await gateway.agents.downloadSandboxFile(sandboxId, { path });
4342
3667
  return await response.blob();
4343
3668
  },
4344
- [gateway, sandboxId, onError]
3669
+ [privateClient, sandboxId, onError]
4345
3670
  );
4346
3671
  const draftExtras = useMemo3(() => {
4347
3672
  if (agent.mode !== "draft") {
@@ -4374,6 +3699,9 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
4374
3699
  onError?.(error);
4375
3700
  }),
4376
3701
  reload: retryLoad,
3702
+ hasOlderHistory,
3703
+ isLoadingOlderHistory,
3704
+ loadOlderHistory,
4377
3705
  draft: draftExtras
4378
3706
  }),
4379
3707
  unstable_enableToolInvocations: true,
@@ -4423,7 +3751,7 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
4423
3751
  }
4424
3752
  function useTrueFoundryAgentRuntime(options) {
4425
3753
  const resolved = resolveTrueFoundryAgentRuntimeOptions(options);
4426
- const { client, agent, gateway } = resolved;
3754
+ const { client, agent, privateClient } = resolved;
4427
3755
  const pendingAgentSpecRef = useRef3(
4428
3756
  agent.mode === "draft" ? agent.defaultAgentSpec : void 0
4429
3757
  );
@@ -4431,14 +3759,14 @@ function useTrueFoundryAgentRuntime(options) {
4431
3759
  const namedAgentName = agent.mode === "named" ? agent.agentName : void 0;
4432
3760
  const threadListAdapter = useMemo3(() => {
4433
3761
  if (agentMode === "draft") {
4434
- if (gateway == null) {
3762
+ if (privateClient == null) {
4435
3763
  throw new Error(
4436
- "Draft agent mode requires a `gateway` TrueFoundryGateway client."
3764
+ "Draft agent mode requires a `privateClient` PrivateAgentSessionClient."
4437
3765
  );
4438
3766
  }
4439
3767
  const draftAgent = agent;
4440
3768
  return createTrueFoundryDraftThreadListAdapter({
4441
- gateway,
3769
+ privateClient,
4442
3770
  defaultAgentSpec: draftAgent.defaultAgentSpec,
4443
3771
  getAgentSpec: () => pendingAgentSpecRef.current ?? draftAgent.defaultAgentSpec
4444
3772
  });
@@ -4447,7 +3775,7 @@ function useTrueFoundryAgentRuntime(options) {
4447
3775
  client,
4448
3776
  agentName: namedAgentName
4449
3777
  });
4450
- }, [agentMode, namedAgentName, client, gateway]);
3778
+ }, [agentMode, namedAgentName, client, privateClient]);
4451
3779
  return useRemoteThreadListRuntime({
4452
3780
  allowNesting: true,
4453
3781
  adapter: threadListAdapter,
@@ -4458,6 +3786,67 @@ function useTrueFoundryAgentRuntime(options) {
4458
3786
  });
4459
3787
  }
4460
3788
 
3789
+ // src/truefoundryOwnedSessionsThreadListAdapter.ts
3790
+ var THREAD_LIST_PAGE_SIZE3 = 20;
3791
+ function ownedSessionTitle(session) {
3792
+ if (session.type === "session/draft") {
3793
+ return draftSessionTitle(session);
3794
+ }
3795
+ return session.title ?? session.agentName;
3796
+ }
3797
+ function createTrueFoundryOwnedSessionsThreadListAdapter(options) {
3798
+ const { privateClient } = options;
3799
+ return {
3800
+ async list({ after } = {}) {
3801
+ const page = await privateClient.listOwnedSessions({
3802
+ limit: THREAD_LIST_PAGE_SIZE3,
3803
+ pageToken: after,
3804
+ startTimestamp: sessionListStartTimestamp()
3805
+ });
3806
+ const threads = page.data.map((session) => ({
3807
+ status: "regular",
3808
+ remoteId: session.id,
3809
+ title: ownedSessionTitle(session),
3810
+ lastMessageAt: new Date(session.updatedAt)
3811
+ }));
3812
+ return {
3813
+ threads,
3814
+ nextCursor: page.response.pagination.nextPageToken ?? void 0
3815
+ };
3816
+ },
3817
+ async initialize() {
3818
+ throw new Error(
3819
+ "Owned sessions history adapter is read-only; create sessions via a named or draft runtime."
3820
+ );
3821
+ },
3822
+ async fetch(remoteId) {
3823
+ const draft = await privateClient.getDraftSession({
3824
+ draftSessionId: remoteId
3825
+ });
3826
+ return {
3827
+ status: "regular",
3828
+ remoteId: draft.id,
3829
+ title: draftSessionTitle(draft),
3830
+ lastMessageAt: new Date(draft.updatedAt)
3831
+ };
3832
+ },
3833
+ async rename() {
3834
+ },
3835
+ async archive() {
3836
+ },
3837
+ async unarchive() {
3838
+ },
3839
+ async delete() {
3840
+ },
3841
+ async generateTitle() {
3842
+ return new ReadableStream();
3843
+ }
3844
+ };
3845
+ }
3846
+
3847
+ // src/index.ts
3848
+ import { PrivateAgentSessionClient } from "truefoundry-gateway-sdk/agents/private";
3849
+
4461
3850
  // src/hooks.ts
4462
3851
  import { useMemo as useMemo4 } from "react";
4463
3852
  import { useAui as useAui2 } from "@assistant-ui/store";
@@ -4522,6 +3911,19 @@ var useTrueFoundryReload = () => {
4522
3911
  const aui = useAui2();
4523
3912
  return () => trueFoundryExtras.get(aui).reload();
4524
3913
  };
3914
+ var useTrueFoundryHistoryPagination = () => {
3915
+ const extras = trueFoundryExtras.use((e) => e, void 0);
3916
+ return useMemo4(
3917
+ () => ({
3918
+ hasOlderHistory: extras?.hasOlderHistory ?? false,
3919
+ isLoadingOlderHistory: extras?.isLoadingOlderHistory ?? false,
3920
+ loadOlderHistory: extras?.loadOlderHistory ?? (async () => {
3921
+ throw new Error("TrueFoundry runtime is not ready yet");
3922
+ })
3923
+ }),
3924
+ [extras]
3925
+ );
3926
+ };
4525
3927
  var useTrueFoundryResetFromTurn = () => {
4526
3928
  const aui = useAui2();
4527
3929
  return (turnId) => trueFoundryExtras.get(aui).resetFromTurn(turnId);
@@ -4589,6 +3991,7 @@ var trueFoundryAttachmentAdapter = {
4589
3991
  }
4590
3992
  };
4591
3993
  export {
3994
+ PrivateAgentSessionClient,
4592
3995
  ROOT_THREAD_ID,
4593
3996
  TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY,
4594
3997
  buildEditedUserMessageContent,
@@ -4600,6 +4003,7 @@ export {
4600
4003
  convertTurnsToThreadMessages,
4601
4004
  createDraftSessionBridge,
4602
4005
  createTrueFoundryDraftThreadListAdapter,
4006
+ createTrueFoundryOwnedSessionsThreadListAdapter,
4603
4007
  createTrueFoundryThreadListAdapter,
4604
4008
  draftSessionTitle,
4605
4009
  findPausedAssistantMessage,
@@ -4619,6 +4023,7 @@ export {
4619
4023
  useTrueFoundryApprovals,
4620
4024
  useTrueFoundryCancel,
4621
4025
  useTrueFoundryDownloadSandboxFile,
4026
+ useTrueFoundryHistoryPagination,
4622
4027
  useTrueFoundryMcpAuth,
4623
4028
  useTrueFoundryReload,
4624
4029
  useTrueFoundryResetFromTurn,