@truefoundry/assistant-ui-runtime 0.1.4 → 0.1.6-rc.0
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/README.md +374 -190
- package/dist/index.d.ts +32 -29
- package/dist/index.js +334 -241
- package/dist/index.js.map +1 -1
- package/dist/plugins/truefoundry-agent-server-adapter/index.d.ts +30 -0
- package/dist/plugins/truefoundry-agent-server-adapter/index.js +198 -0
- package/dist/plugins/truefoundry-agent-server-adapter/index.js.map +1 -0
- package/dist/types-VUBzoJT2.d.ts +462 -0
- package/package.json +12 -4
- package/src/askUserQuestion.ts +3 -3
- package/src/collectPending.ts +1 -1
- package/src/convertTurnMessages.test.ts +141 -196
- package/src/convertTurnMessages.ts +131 -77
- package/src/createSubAgent.ts +1 -1
- package/src/draftAgentConfig.test.ts +26 -29
- package/src/extractTurnUserText.ts +1 -1
- package/src/foldPeerThreads.test.ts +1 -1
- package/src/foldPeerThreads.ts +3 -2
- package/src/index.ts +39 -4
- package/src/listPages.ts +21 -0
- package/src/loadSessionSnapshot.test.ts +9 -8
- package/src/loadSessionSnapshot.ts +9 -14
- package/src/mcpAuth.ts +6 -3
- package/src/messageCustomMetadata.ts +1 -1
- package/src/modelMessageContent.ts +1 -1
- package/src/modelMessageImageContent.test.ts +1 -1
- package/src/modelMessageImageContent.ts +7 -6
- package/src/plugins/truefoundry-agent-server-adapter/index.ts +285 -0
- package/src/private/agentSpec.ts +8 -3
- package/src/private/draftSessionBridge.ts +14 -13
- package/src/private/truefoundryDraftThreadListAdapter.test.ts +44 -49
- package/src/private/truefoundryDraftThreadListAdapter.ts +22 -16
- package/src/requiredActionInputs.ts +1 -1
- package/src/requiredActionsFromActiveUpdate.test.ts +1 -1
- package/src/server/eventUtils.ts +120 -0
- package/src/server/events.ts +246 -0
- package/src/server/index.ts +66 -0
- package/src/server/types.ts +313 -0
- package/src/sessionSnapshot.ts +1 -1
- package/src/sessions.ts +5 -21
- package/src/streamTurn.test.ts +175 -158
- package/src/streamTurn.ts +51 -57
- package/src/toolApproval.ts +4 -4
- package/src/toolResponse.ts +4 -4
- package/src/truefoundryExtras.ts +1 -1
- package/src/truefoundryOwnedSessionsThreadListAdapter.test.ts +26 -29
- package/src/truefoundryOwnedSessionsThreadListAdapter.ts +18 -23
- package/src/truefoundryThreadListAdapter.test.ts +16 -18
- package/src/truefoundryThreadListAdapter.ts +9 -9
- package/src/turnEventHelpers.ts +1 -1
- package/src/types.ts +2 -16
- package/src/useTrueFoundryAgentMessages.test.tsx +38 -70
- package/src/useTrueFoundryAgentMessages.ts +33 -45
- package/src/useTrueFoundryAgentRuntime.ts +11 -28
- package/src/private/bindDraftAgentSession.test.ts +0 -54
- package/src/private/bindDraftAgentSession.ts +0 -28
- package/src/private/getGatewayFromPrivateClient.ts +0 -13
package/dist/index.js
CHANGED
|
@@ -88,9 +88,10 @@ function findApprovalRequiredInTurn(turn) {
|
|
|
88
88
|
if (turn.state.status !== "done") {
|
|
89
89
|
return void 0;
|
|
90
90
|
}
|
|
91
|
-
|
|
91
|
+
const found = turn.state.requiredActions?.find(
|
|
92
92
|
(action) => action.type === "tool.approval_required"
|
|
93
93
|
);
|
|
94
|
+
return found?.type === "tool.approval_required" ? found : void 0;
|
|
94
95
|
}
|
|
95
96
|
function toolCallPartHasPendingApproval(part) {
|
|
96
97
|
return hasPendingToolApproval(part.approval);
|
|
@@ -250,10 +251,93 @@ function toTrueFoundryApprovalInputs(message, response, defaultThreadId = ROOT_T
|
|
|
250
251
|
return collectApprovalInputs(updated, defaultThreadId);
|
|
251
252
|
}
|
|
252
253
|
|
|
253
|
-
// src/
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
}
|
|
254
|
+
// src/server/eventUtils.ts
|
|
255
|
+
function isEventDelta(event) {
|
|
256
|
+
return typeof event.type === "string" && event.type.endsWith(".delta");
|
|
257
|
+
}
|
|
258
|
+
function mergeEventDelta(base, delta) {
|
|
259
|
+
if (base.id !== delta.id) {
|
|
260
|
+
throw new Error(
|
|
261
|
+
`Cannot merge delta into a different event: base id "${base.id}" != delta id "${delta.id}".`
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
if (delta.type === "model.message.delta" && base.type === "model.message") {
|
|
265
|
+
mergeModelMessageDelta(base, delta);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function asToolInfo(value) {
|
|
269
|
+
if (value == null || typeof value !== "object") {
|
|
270
|
+
return void 0;
|
|
271
|
+
}
|
|
272
|
+
return value;
|
|
273
|
+
}
|
|
274
|
+
function mergeModelMessageDelta(base, delta) {
|
|
275
|
+
if (delta.content) {
|
|
276
|
+
if (base.content === void 0 || base.content === null || typeof base.content === "string") {
|
|
277
|
+
base.content = (base.content ?? "") + delta.content;
|
|
278
|
+
} else {
|
|
279
|
+
const last = base.content[base.content.length - 1];
|
|
280
|
+
if (last && last.type === "text") {
|
|
281
|
+
last.text += delta.content;
|
|
282
|
+
} else {
|
|
283
|
+
base.content.push({ type: "text", text: delta.content });
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
if (delta.refusal) {
|
|
288
|
+
base.refusal = (base.refusal ?? "") + delta.refusal;
|
|
289
|
+
}
|
|
290
|
+
if (delta.toolCalls) {
|
|
291
|
+
base.toolCalls ??= [];
|
|
292
|
+
for (const d of delta.toolCalls) {
|
|
293
|
+
let tc = base.toolCalls[d.index];
|
|
294
|
+
if (tc === void 0) {
|
|
295
|
+
const toolInfo2 = asToolInfo(d.toolInfo);
|
|
296
|
+
tc = {
|
|
297
|
+
id: d.id ?? "",
|
|
298
|
+
type: d.type ?? "function",
|
|
299
|
+
function: {
|
|
300
|
+
name: d.function?.name ?? "",
|
|
301
|
+
arguments: ""
|
|
302
|
+
},
|
|
303
|
+
...toolInfo2 != null ? { toolInfo: toolInfo2 } : {}
|
|
304
|
+
};
|
|
305
|
+
base.toolCalls[d.index] = tc;
|
|
306
|
+
}
|
|
307
|
+
if (d.id) {
|
|
308
|
+
tc.id = d.id;
|
|
309
|
+
}
|
|
310
|
+
if (d.type) {
|
|
311
|
+
tc.type = d.type;
|
|
312
|
+
}
|
|
313
|
+
if (d.function?.name) {
|
|
314
|
+
tc.function.name = d.function.name;
|
|
315
|
+
}
|
|
316
|
+
if (d.function?.arguments) {
|
|
317
|
+
tc.function.arguments += d.function.arguments;
|
|
318
|
+
}
|
|
319
|
+
const toolInfo = asToolInfo(d.toolInfo);
|
|
320
|
+
if (toolInfo != null) {
|
|
321
|
+
tc.toolInfo = toolInfo;
|
|
322
|
+
}
|
|
323
|
+
if (d.providerSpecificFields) {
|
|
324
|
+
tc.providerSpecificFields = {
|
|
325
|
+
...tc.providerSpecificFields ?? {},
|
|
326
|
+
...d.providerSpecificFields
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (delta.finishReason) {
|
|
332
|
+
base.finishReason = delta.finishReason;
|
|
333
|
+
}
|
|
334
|
+
if (delta.reasoningContent) {
|
|
335
|
+
base.reasoningContent = (base.reasoningContent ?? "") + delta.reasoningContent;
|
|
336
|
+
}
|
|
337
|
+
if (delta.usage) {
|
|
338
|
+
base.usage = delta.usage;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
257
341
|
|
|
258
342
|
// src/askUserQuestion.ts
|
|
259
343
|
function parseAskUserQuestionArgs(argsText) {
|
|
@@ -283,7 +367,6 @@ function isCreateSubAgentToolCall(toolCall) {
|
|
|
283
367
|
}
|
|
284
368
|
|
|
285
369
|
// src/modelMessageImageContent.ts
|
|
286
|
-
import { isEventDelta, mergeEventDelta } from "truefoundry-gateway-sdk/agents";
|
|
287
370
|
function parseDataUriMime(data) {
|
|
288
371
|
if (!data.startsWith("data:")) {
|
|
289
372
|
return "image/png";
|
|
@@ -545,7 +628,7 @@ function ingestEventIntoBucket(bucket, message) {
|
|
|
545
628
|
if (isTurnScopedEvent(message)) {
|
|
546
629
|
return;
|
|
547
630
|
}
|
|
548
|
-
if (
|
|
631
|
+
if (isEventDelta(message)) {
|
|
549
632
|
const base = bucket.events.get(message.id);
|
|
550
633
|
if (base != null) {
|
|
551
634
|
mergeStreamEventDelta(base, message);
|
|
@@ -899,9 +982,10 @@ function findResponseRequiredInTurn(turn) {
|
|
|
899
982
|
if (turn.state.status !== "done") {
|
|
900
983
|
return void 0;
|
|
901
984
|
}
|
|
902
|
-
|
|
985
|
+
const found = turn.state.requiredActions?.find(
|
|
903
986
|
(action) => action.type === "tool.response_required"
|
|
904
987
|
);
|
|
988
|
+
return found?.type === "tool.response_required" ? found : void 0;
|
|
905
989
|
}
|
|
906
990
|
function applyToolResponseToToolCall(part, content) {
|
|
907
991
|
return { ...part, result: content };
|
|
@@ -1150,6 +1234,21 @@ function deriveSandboxId(messages) {
|
|
|
1150
1234
|
return void 0;
|
|
1151
1235
|
}
|
|
1152
1236
|
|
|
1237
|
+
// src/listPages.ts
|
|
1238
|
+
async function drainListPages(fetchPage) {
|
|
1239
|
+
const items = [];
|
|
1240
|
+
let pageToken;
|
|
1241
|
+
for (; ; ) {
|
|
1242
|
+
const page = await fetchPage(pageToken);
|
|
1243
|
+
items.push(...page.data);
|
|
1244
|
+
if (page.nextPageToken == null || page.nextPageToken === "") {
|
|
1245
|
+
break;
|
|
1246
|
+
}
|
|
1247
|
+
pageToken = page.nextPageToken;
|
|
1248
|
+
}
|
|
1249
|
+
return items;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1153
1252
|
// src/extractTurnUserText.ts
|
|
1154
1253
|
function extractTurnUserText(input) {
|
|
1155
1254
|
const parts = [];
|
|
@@ -1187,9 +1286,10 @@ function buildMcpAuthTextParts(servers) {
|
|
|
1187
1286
|
return [{ type: "text", text }];
|
|
1188
1287
|
}
|
|
1189
1288
|
function findMcpAuthRequired(requiredActions) {
|
|
1190
|
-
|
|
1289
|
+
const found = requiredActions?.find(
|
|
1191
1290
|
(action) => action.type === "mcp.auth_required"
|
|
1192
1291
|
);
|
|
1292
|
+
return found?.type === "mcp.auth_required" ? found : void 0;
|
|
1193
1293
|
}
|
|
1194
1294
|
function mcpAuthAssistantStatus() {
|
|
1195
1295
|
return { type: "requires-action", reason: "interrupt" };
|
|
@@ -1329,28 +1429,28 @@ function oldestCompleteTurnGroupState(itemsAsc) {
|
|
|
1329
1429
|
}
|
|
1330
1430
|
return extractTurnUserText(created.event.input) != null ? "user-group" : "continuation";
|
|
1331
1431
|
}
|
|
1332
|
-
async function fetchSessionEventsPage(
|
|
1333
|
-
const page = await
|
|
1432
|
+
async function fetchSessionEventsPage(server, sessionId, options) {
|
|
1433
|
+
const page = await server.listEvents({
|
|
1434
|
+
sessionId,
|
|
1334
1435
|
limit: SESSION_EVENTS_PAGE_SIZE,
|
|
1335
1436
|
...options?.lastTurnId != null ? { lastTurnId: options.lastTurnId } : {},
|
|
1336
1437
|
...options?.pageToken != null ? { pageToken: options.pageToken } : {}
|
|
1337
1438
|
});
|
|
1338
|
-
const
|
|
1339
|
-
const
|
|
1340
|
-
const hasOlder = typeof page.hasNextPage === "function" ? page.hasNextPage() : olderPageToken != null && olderPageToken !== "";
|
|
1439
|
+
const olderPageToken = page.nextPageToken;
|
|
1440
|
+
const hasOlder = olderPageToken != null && olderPageToken !== "";
|
|
1341
1441
|
return {
|
|
1342
1442
|
itemsNewestFirst: page.data,
|
|
1343
1443
|
...olderPageToken != null && olderPageToken !== "" ? { olderPageToken } : {},
|
|
1344
1444
|
hasOlder
|
|
1345
1445
|
};
|
|
1346
1446
|
}
|
|
1347
|
-
async function fetchSessionEventsWindow(
|
|
1447
|
+
async function fetchSessionEventsWindow(server, sessionId, options) {
|
|
1348
1448
|
let itemsNewestFirst = [];
|
|
1349
1449
|
let pageToken = options?.pageToken;
|
|
1350
1450
|
let olderPageToken;
|
|
1351
1451
|
let hasOlder = false;
|
|
1352
1452
|
for (let pageCount = 0; pageCount < MAX_HISTORY_BOUNDARY_PAGES; pageCount++) {
|
|
1353
|
-
const page = await fetchSessionEventsPage(
|
|
1453
|
+
const page = await fetchSessionEventsPage(server, sessionId, {
|
|
1354
1454
|
...options,
|
|
1355
1455
|
...pageToken != null ? { pageToken } : {}
|
|
1356
1456
|
});
|
|
@@ -1378,14 +1478,15 @@ async function fetchSessionEventsWindow(session, options) {
|
|
|
1378
1478
|
hasOlder
|
|
1379
1479
|
};
|
|
1380
1480
|
}
|
|
1381
|
-
async function fetchAllSessionEvents(
|
|
1382
|
-
const items =
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1481
|
+
async function fetchAllSessionEvents(server, sessionId, options) {
|
|
1482
|
+
const items = await drainListPages(
|
|
1483
|
+
(pageToken) => server.listEvents({
|
|
1484
|
+
sessionId,
|
|
1485
|
+
limit: SESSION_EVENTS_PAGE_SIZE,
|
|
1486
|
+
...options?.lastTurnId != null ? { lastTurnId: options.lastTurnId } : {},
|
|
1487
|
+
...pageToken != null ? { pageToken } : {}
|
|
1488
|
+
})
|
|
1489
|
+
);
|
|
1389
1490
|
items.reverse();
|
|
1390
1491
|
return items;
|
|
1391
1492
|
}
|
|
@@ -1520,11 +1621,11 @@ function attachRunningTurn(snapshot, runningTurn) {
|
|
|
1520
1621
|
} : {}
|
|
1521
1622
|
});
|
|
1522
1623
|
}
|
|
1523
|
-
async function buildSnapshotFromSessionEvents(
|
|
1524
|
-
const turnsPage = await
|
|
1624
|
+
async function buildSnapshotFromSessionEvents(server, sessionId, onProgress) {
|
|
1625
|
+
const turnsPage = await server.listTurns({ sessionId, limit: 1 });
|
|
1525
1626
|
const newestTurn = turnsPage.data[0];
|
|
1526
1627
|
const runningTurn = newestTurn?.state?.status === "running" ? newestTurn : void 0;
|
|
1527
|
-
const window = await fetchSessionEventsWindow(
|
|
1628
|
+
const window = await fetchSessionEventsWindow(server, sessionId);
|
|
1528
1629
|
const historyPagination = {
|
|
1529
1630
|
hasOlder: window.hasOlder,
|
|
1530
1631
|
...window.olderPageToken != null ? { olderPageToken: window.olderPageToken } : {}
|
|
@@ -1537,12 +1638,12 @@ async function buildSnapshotFromSessionEvents(session, onProgress) {
|
|
|
1537
1638
|
});
|
|
1538
1639
|
return attachRunningTurn(withHistory, runningTurn);
|
|
1539
1640
|
}
|
|
1540
|
-
async function prependOlderSessionHistory(
|
|
1641
|
+
async function prependOlderSessionHistory(server, sessionId, snapshot) {
|
|
1541
1642
|
const pagination = snapshot.historyPagination;
|
|
1542
1643
|
if (pagination?.hasOlder !== true || pagination.olderPageToken == null) {
|
|
1543
1644
|
return snapshot;
|
|
1544
1645
|
}
|
|
1545
|
-
const window = await fetchSessionEventsWindow(
|
|
1646
|
+
const window = await fetchSessionEventsWindow(server, sessionId, {
|
|
1546
1647
|
pageToken: pagination.olderPageToken
|
|
1547
1648
|
});
|
|
1548
1649
|
if (window.itemsAsc.length === 0) {
|
|
@@ -1694,22 +1795,36 @@ function buildAssistantMessage(turnId, content, createdAt, status, custom = {},
|
|
|
1694
1795
|
}
|
|
1695
1796
|
};
|
|
1696
1797
|
}
|
|
1697
|
-
async function ingestTurnEventsIntoFold(
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1798
|
+
async function ingestTurnEventsIntoFold(server, sessionId, turnId, foldState) {
|
|
1799
|
+
if (server.listTurnEvents == null) {
|
|
1800
|
+
return;
|
|
1801
|
+
}
|
|
1802
|
+
const events = await drainListPages(
|
|
1803
|
+
(pageToken) => server.listTurnEvents({
|
|
1804
|
+
sessionId,
|
|
1805
|
+
turnId,
|
|
1806
|
+
order: "asc",
|
|
1807
|
+
limit: TURN_EVENTS_PAGE_SIZE,
|
|
1808
|
+
...pageToken != null ? { pageToken } : {}
|
|
1809
|
+
})
|
|
1810
|
+
);
|
|
1811
|
+
for (const event of events) {
|
|
1702
1812
|
ingestTurnEvent(foldState, event);
|
|
1703
1813
|
}
|
|
1704
1814
|
}
|
|
1705
|
-
async function fetchTurnEvents(
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
order: "asc",
|
|
1709
|
-
limit: TURN_EVENTS_PAGE_SIZE
|
|
1710
|
-
})) {
|
|
1711
|
-
events.push(event);
|
|
1815
|
+
async function fetchTurnEvents(server, sessionId, turnId) {
|
|
1816
|
+
if (server.listTurnEvents == null) {
|
|
1817
|
+
return [];
|
|
1712
1818
|
}
|
|
1819
|
+
const events = await drainListPages(
|
|
1820
|
+
(pageToken) => server.listTurnEvents({
|
|
1821
|
+
sessionId,
|
|
1822
|
+
turnId,
|
|
1823
|
+
order: "asc",
|
|
1824
|
+
limit: TURN_EVENTS_PAGE_SIZE,
|
|
1825
|
+
...pageToken != null ? { pageToken } : {}
|
|
1826
|
+
})
|
|
1827
|
+
);
|
|
1713
1828
|
return events;
|
|
1714
1829
|
}
|
|
1715
1830
|
function ingestCollectedEventsIntoFold(foldState, events) {
|
|
@@ -1717,16 +1832,18 @@ function ingestCollectedEventsIntoFold(foldState, events) {
|
|
|
1717
1832
|
ingestTurnEvent(foldState, event);
|
|
1718
1833
|
}
|
|
1719
1834
|
}
|
|
1720
|
-
async function fetchAllTurnEventsWithConcurrency(turns, concurrency) {
|
|
1835
|
+
async function fetchAllTurnEventsWithConcurrency(server, sessionId, turns, concurrency) {
|
|
1721
1836
|
const results = new Array(turns.length);
|
|
1722
1837
|
const pool = /* @__PURE__ */ new Set();
|
|
1723
1838
|
for (let i = 0; i < turns.length; i++) {
|
|
1724
1839
|
const idx = i;
|
|
1725
1840
|
const turn = turns[idx];
|
|
1726
|
-
const p = fetchTurnEvents(turn).then(
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1841
|
+
const p = fetchTurnEvents(server, sessionId, turn.id).then(
|
|
1842
|
+
(events) => {
|
|
1843
|
+
results[idx] = events;
|
|
1844
|
+
pool.delete(p);
|
|
1845
|
+
}
|
|
1846
|
+
);
|
|
1730
1847
|
pool.add(p);
|
|
1731
1848
|
if (pool.size >= concurrency) await Promise.race(pool);
|
|
1732
1849
|
}
|
|
@@ -2011,13 +2128,18 @@ function ingestTurnsIntoSnapshot(snapshot, turns, eventArrays) {
|
|
|
2011
2128
|
}
|
|
2012
2129
|
return runningTurn;
|
|
2013
2130
|
}
|
|
2014
|
-
async function buildSnapshotFromSession(
|
|
2015
|
-
const snapshot = await buildSnapshotFromSessionEvents(
|
|
2131
|
+
async function buildSnapshotFromSession(server, sessionId, concurrency = DEFAULT_LIST_EVENTS_CONCURRENCY) {
|
|
2132
|
+
const snapshot = await buildSnapshotFromSessionEvents(server, sessionId);
|
|
2016
2133
|
if (snapshot.runningTurn == null) {
|
|
2017
2134
|
return snapshot;
|
|
2018
2135
|
}
|
|
2019
2136
|
const turn = snapshot.runningTurn;
|
|
2020
|
-
const eventArrays = await fetchAllTurnEventsWithConcurrency(
|
|
2137
|
+
const eventArrays = await fetchAllTurnEventsWithConcurrency(
|
|
2138
|
+
server,
|
|
2139
|
+
sessionId,
|
|
2140
|
+
[turn],
|
|
2141
|
+
concurrency
|
|
2142
|
+
);
|
|
2021
2143
|
ingestTurnsIntoSnapshot(snapshot, [turn], eventArrays);
|
|
2022
2144
|
return replaceSessionSnapshot(snapshot, {
|
|
2023
2145
|
runningTurn: turn,
|
|
@@ -2026,59 +2148,67 @@ async function buildSnapshotFromSession(session, concurrency = DEFAULT_LIST_EVEN
|
|
|
2026
2148
|
pendingUser: void 0
|
|
2027
2149
|
});
|
|
2028
2150
|
}
|
|
2029
|
-
async function buildSnapshotBeforeTurn(
|
|
2030
|
-
const turns = await listSessionTurnsOrdered(
|
|
2151
|
+
async function buildSnapshotBeforeTurn(server, sessionId, beforeTurnId, concurrency = DEFAULT_LIST_EVENTS_CONCURRENCY) {
|
|
2152
|
+
const turns = await listSessionTurnsOrdered(server, sessionId);
|
|
2031
2153
|
const beforeIndex = turns.findIndex((turn) => turn.id === beforeTurnId);
|
|
2032
2154
|
if (beforeIndex === -1) {
|
|
2033
2155
|
throw new Error(`Turn ${beforeTurnId} not found in session`);
|
|
2034
2156
|
}
|
|
2035
|
-
return buildSnapshotBeforeTurnIndex(
|
|
2157
|
+
return buildSnapshotBeforeTurnIndex(
|
|
2158
|
+
server,
|
|
2159
|
+
sessionId,
|
|
2160
|
+
beforeIndex,
|
|
2161
|
+
concurrency,
|
|
2162
|
+
turns
|
|
2163
|
+
);
|
|
2036
2164
|
}
|
|
2037
|
-
async function buildSnapshotBeforeTurnIndex(
|
|
2165
|
+
async function buildSnapshotBeforeTurnIndex(server, sessionId, turnIndex, _concurrency = DEFAULT_LIST_EVENTS_CONCURRENCY, orderedTurns) {
|
|
2038
2166
|
if (turnIndex <= 0) {
|
|
2039
2167
|
return createEmptySessionSnapshot();
|
|
2040
2168
|
}
|
|
2041
|
-
const turns = orderedTurns ?? await listSessionTurnsOrdered(
|
|
2169
|
+
const turns = orderedTurns ?? await listSessionTurnsOrdered(server, sessionId);
|
|
2042
2170
|
const turnsToInclude = turns.slice(0, turnIndex);
|
|
2043
2171
|
const lastTurnId = turnsToInclude.at(-1)?.id;
|
|
2044
2172
|
if (lastTurnId == null) {
|
|
2045
2173
|
return createEmptySessionSnapshot();
|
|
2046
2174
|
}
|
|
2047
|
-
const items = await fetchAllSessionEvents(
|
|
2175
|
+
const items = await fetchAllSessionEvents(server, sessionId, { lastTurnId });
|
|
2048
2176
|
const snapshot = createEmptySessionSnapshot();
|
|
2049
2177
|
ingestSessionEventsIntoSnapshot(snapshot, items);
|
|
2050
2178
|
return snapshot;
|
|
2051
2179
|
}
|
|
2052
|
-
async function resolveGatewayBranchPreviousTurnId(
|
|
2180
|
+
async function resolveGatewayBranchPreviousTurnId(server, sessionId, turnIndex, orderedTurns) {
|
|
2053
2181
|
if (turnIndex <= 0) {
|
|
2054
|
-
return
|
|
2182
|
+
return "none";
|
|
2055
2183
|
}
|
|
2056
|
-
const turns = orderedTurns ?? await listSessionTurnsOrdered(
|
|
2057
|
-
return turns[turnIndex - 1]?.id ??
|
|
2184
|
+
const turns = orderedTurns ?? await listSessionTurnsOrdered(server, sessionId);
|
|
2185
|
+
return turns[turnIndex - 1]?.id ?? "none";
|
|
2058
2186
|
}
|
|
2059
|
-
async function resolveGatewayBranchPreviousTurnIdForTurn(
|
|
2060
|
-
const turns = await listSessionTurnsOrdered(
|
|
2187
|
+
async function resolveGatewayBranchPreviousTurnIdForTurn(server, sessionId, turnId) {
|
|
2188
|
+
const turns = await listSessionTurnsOrdered(server, sessionId);
|
|
2061
2189
|
const turnIndex = turns.findIndex((turn) => turn.id === turnId);
|
|
2062
|
-
return resolveGatewayBranchPreviousTurnId(
|
|
2190
|
+
return resolveGatewayBranchPreviousTurnId(server, sessionId, turnIndex, turns);
|
|
2063
2191
|
}
|
|
2064
|
-
async function listSessionTurnsOrdered(
|
|
2065
|
-
const turns =
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2192
|
+
async function listSessionTurnsOrdered(server, sessionId) {
|
|
2193
|
+
const turns = await drainListPages(
|
|
2194
|
+
(pageToken) => server.listTurns({
|
|
2195
|
+
sessionId,
|
|
2196
|
+
...pageToken != null ? { pageToken } : {}
|
|
2197
|
+
})
|
|
2198
|
+
);
|
|
2069
2199
|
turns.reverse();
|
|
2070
2200
|
return turns;
|
|
2071
2201
|
}
|
|
2072
|
-
async function buildTurnAssistantContent(turn, foldState) {
|
|
2202
|
+
async function buildTurnAssistantContent(server, sessionId, turn, foldState) {
|
|
2073
2203
|
const state = foldState ?? new PeerThreadFoldState();
|
|
2074
2204
|
const beforeCount = state.threads.get(ROOT_THREAD_ID)?.modelMessageIds.length ?? 0;
|
|
2075
|
-
await ingestTurnEventsIntoFold(
|
|
2205
|
+
await ingestTurnEventsIntoFold(server, sessionId, turn.id, state);
|
|
2076
2206
|
const afterIds = state.threads.get(ROOT_THREAD_ID)?.modelMessageIds ?? [];
|
|
2077
2207
|
const rootModelMessageIds = afterIds.slice(beforeCount);
|
|
2078
2208
|
return buildTurnUpdateFromFold(state, turn, rootModelMessageIds).content;
|
|
2079
2209
|
}
|
|
2080
|
-
async function convertTurnsToThreadMessages(
|
|
2081
|
-
const snapshot = await buildSnapshotFromSession(
|
|
2210
|
+
async function convertTurnsToThreadMessages(server, sessionId) {
|
|
2211
|
+
const snapshot = await buildSnapshotFromSession(server, sessionId);
|
|
2082
2212
|
const messages = projectSessionMessages(snapshot);
|
|
2083
2213
|
return {
|
|
2084
2214
|
messages,
|
|
@@ -2218,7 +2348,7 @@ function buildMcpAuthUpdate(pendingMcpAuth, foldState, groupRootBaseline) {
|
|
|
2218
2348
|
metadata: { custom: mcpAuthMessageCustom(pendingMcpAuth.mcpServers) }
|
|
2219
2349
|
};
|
|
2220
2350
|
}
|
|
2221
|
-
async function* streamTurnEvents(stream, foldState, groupRootBaseline) {
|
|
2351
|
+
async function* streamTurnEvents(stream, foldState, groupRootBaseline, onTurnIdAvailable) {
|
|
2222
2352
|
let pendingMcpAuth;
|
|
2223
2353
|
let sandboxId;
|
|
2224
2354
|
let sandboxIdYielded = false;
|
|
@@ -2239,6 +2369,10 @@ async function* streamTurnEvents(stream, foldState, groupRootBaseline) {
|
|
|
2239
2369
|
};
|
|
2240
2370
|
for await (const data of stream) {
|
|
2241
2371
|
const event = data.event;
|
|
2372
|
+
if (event.type === "turn.created") {
|
|
2373
|
+
onTurnIdAvailable?.(event.turnId);
|
|
2374
|
+
continue;
|
|
2375
|
+
}
|
|
2242
2376
|
if (event.type === "sandbox.created") {
|
|
2243
2377
|
sandboxId = event.sandboxId;
|
|
2244
2378
|
continue;
|
|
@@ -2326,30 +2460,25 @@ function repositoryItemsFromMessages(messages) {
|
|
|
2326
2460
|
return items;
|
|
2327
2461
|
}
|
|
2328
2462
|
|
|
2329
|
-
// src/private/getGatewayFromPrivateClient.ts
|
|
2330
|
-
function getGatewayFromPrivateClient(privateClient) {
|
|
2331
|
-
const internal = privateClient;
|
|
2332
|
-
if (internal.client == null) {
|
|
2333
|
-
throw new Error("PrivateAgentSessionClient is missing an internal gateway client.");
|
|
2334
|
-
}
|
|
2335
|
-
return internal.client;
|
|
2336
|
-
}
|
|
2337
|
-
|
|
2338
2463
|
// src/private/draftSessionBridge.ts
|
|
2339
2464
|
var DRAFT_SESSION_LAST_UPDATED_AT_HEADER = "x-tfy-session-last-updated-at";
|
|
2340
|
-
function createDraftSessionBridge(
|
|
2465
|
+
function createDraftSessionBridge(server) {
|
|
2341
2466
|
return {
|
|
2342
2467
|
async getDraftAgentSpec(draftSessionId) {
|
|
2343
|
-
const
|
|
2344
|
-
|
|
2468
|
+
const session = await server.getSession({ sessionId: draftSessionId });
|
|
2469
|
+
if (session.agentSpec == null) {
|
|
2470
|
+
throw new Error(
|
|
2471
|
+
`Session ${draftSessionId} has no agentSpec (isMutable=${session.isMutable}).`
|
|
2472
|
+
);
|
|
2473
|
+
}
|
|
2474
|
+
return session.agentSpec;
|
|
2345
2475
|
},
|
|
2346
2476
|
async syncAgentSpec(draftSessionId, agentSpec) {
|
|
2347
|
-
const
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
return response.data.updatedAt;
|
|
2477
|
+
const updated = await server.updateSession({
|
|
2478
|
+
sessionId: draftSessionId,
|
|
2479
|
+
agentSpec
|
|
2480
|
+
});
|
|
2481
|
+
return updated.updatedAt;
|
|
2353
2482
|
}
|
|
2354
2483
|
};
|
|
2355
2484
|
}
|
|
@@ -2385,39 +2514,43 @@ function sessionListStartTimestamp() {
|
|
|
2385
2514
|
// src/private/truefoundryDraftThreadListAdapter.ts
|
|
2386
2515
|
var THREAD_LIST_PAGE_SIZE = 20;
|
|
2387
2516
|
function createTrueFoundryDraftThreadListAdapter(options) {
|
|
2388
|
-
const {
|
|
2517
|
+
const { server, defaultAgentSpec, getAgentSpec } = options;
|
|
2389
2518
|
return {
|
|
2390
2519
|
async list({ after } = {}) {
|
|
2391
|
-
const page = await
|
|
2520
|
+
const page = await server.listSessions({
|
|
2392
2521
|
limit: THREAD_LIST_PAGE_SIZE,
|
|
2393
2522
|
pageToken: after,
|
|
2394
2523
|
startTimestamp: sessionListStartTimestamp()
|
|
2395
2524
|
});
|
|
2396
|
-
const threads = page.data.map((draft) => ({
|
|
2525
|
+
const threads = page.data.filter((session) => session.isMutable).map((draft) => ({
|
|
2397
2526
|
status: "regular",
|
|
2398
2527
|
remoteId: draft.id,
|
|
2399
|
-
title: draftSessionTitle(
|
|
2528
|
+
title: draftSessionTitle({
|
|
2529
|
+
title: draft.title,
|
|
2530
|
+
agentSpec: draft.agentSpec ?? defaultAgentSpec
|
|
2531
|
+
}),
|
|
2400
2532
|
lastMessageAt: new Date(draft.updatedAt)
|
|
2401
2533
|
}));
|
|
2402
2534
|
return {
|
|
2403
2535
|
threads,
|
|
2404
|
-
nextCursor: page.
|
|
2536
|
+
nextCursor: page.nextPageToken ?? void 0
|
|
2405
2537
|
};
|
|
2406
2538
|
},
|
|
2407
2539
|
async initialize(_threadId) {
|
|
2408
|
-
const draft = await
|
|
2540
|
+
const draft = await server.createSession({
|
|
2409
2541
|
agentSpec: getAgentSpec?.() ?? defaultAgentSpec
|
|
2410
2542
|
});
|
|
2411
2543
|
return { remoteId: draft.id, externalId: void 0 };
|
|
2412
2544
|
},
|
|
2413
2545
|
async fetch(remoteId) {
|
|
2414
|
-
const draft = await
|
|
2415
|
-
draftSessionId: remoteId
|
|
2416
|
-
});
|
|
2546
|
+
const draft = await server.getSession({ sessionId: remoteId });
|
|
2417
2547
|
return {
|
|
2418
2548
|
status: "regular",
|
|
2419
2549
|
remoteId: draft.id,
|
|
2420
|
-
title: draftSessionTitle(
|
|
2550
|
+
title: draftSessionTitle({
|
|
2551
|
+
title: draft.title,
|
|
2552
|
+
agentSpec: draft.agentSpec ?? defaultAgentSpec
|
|
2553
|
+
}),
|
|
2421
2554
|
lastMessageAt: new Date(draft.updatedAt)
|
|
2422
2555
|
};
|
|
2423
2556
|
},
|
|
@@ -2450,30 +2583,12 @@ var EMPTY_DRAFT_EXTRAS = {
|
|
|
2450
2583
|
}
|
|
2451
2584
|
};
|
|
2452
2585
|
|
|
2453
|
-
// src/private/bindDraftAgentSession.ts
|
|
2454
|
-
var inflightByDraftId = /* @__PURE__ */ new Map();
|
|
2455
|
-
async function bindDraftAgentSession(privateClient, draftSessionId) {
|
|
2456
|
-
let inflight = inflightByDraftId.get(draftSessionId);
|
|
2457
|
-
if (inflight == null) {
|
|
2458
|
-
inflight = privateClient.getDraftSession({ draftSessionId }).then((draft) => draft).finally(() => {
|
|
2459
|
-
if (inflightByDraftId.get(draftSessionId) === inflight) {
|
|
2460
|
-
inflightByDraftId.delete(draftSessionId);
|
|
2461
|
-
}
|
|
2462
|
-
});
|
|
2463
|
-
inflightByDraftId.set(draftSessionId, inflight);
|
|
2464
|
-
}
|
|
2465
|
-
return inflight;
|
|
2466
|
-
}
|
|
2467
|
-
|
|
2468
2586
|
// src/sessions.ts
|
|
2469
2587
|
var inflightBySessionId = /* @__PURE__ */ new Map();
|
|
2470
|
-
function getSession(
|
|
2471
|
-
if (options?.privateClient != null) {
|
|
2472
|
-
return bindDraftAgentSession(options.privateClient, sessionId);
|
|
2473
|
-
}
|
|
2588
|
+
function getSession(server, sessionId) {
|
|
2474
2589
|
let inflight = inflightBySessionId.get(sessionId);
|
|
2475
2590
|
if (inflight == null) {
|
|
2476
|
-
inflight =
|
|
2591
|
+
inflight = server.getSession({ sessionId }).finally(() => {
|
|
2477
2592
|
if (inflightBySessionId.get(sessionId) === inflight) {
|
|
2478
2593
|
inflightBySessionId.delete(sessionId);
|
|
2479
2594
|
}
|
|
@@ -2486,10 +2601,10 @@ function getSession(client, sessionId, options) {
|
|
|
2486
2601
|
// src/truefoundryThreadListAdapter.ts
|
|
2487
2602
|
var THREAD_LIST_PAGE_SIZE2 = 20;
|
|
2488
2603
|
function createTrueFoundryThreadListAdapter(options) {
|
|
2489
|
-
const {
|
|
2604
|
+
const { server, agentName } = options;
|
|
2490
2605
|
return {
|
|
2491
2606
|
async list({ after } = {}) {
|
|
2492
|
-
const page = await
|
|
2607
|
+
const page = await server.listSessions({
|
|
2493
2608
|
agentName,
|
|
2494
2609
|
limit: THREAD_LIST_PAGE_SIZE2,
|
|
2495
2610
|
pageToken: after,
|
|
@@ -2498,24 +2613,24 @@ function createTrueFoundryThreadListAdapter(options) {
|
|
|
2498
2613
|
const threads = page.data.map((session) => ({
|
|
2499
2614
|
status: "regular",
|
|
2500
2615
|
remoteId: session.id,
|
|
2501
|
-
title: session.title,
|
|
2616
|
+
title: session.title ?? void 0,
|
|
2502
2617
|
lastMessageAt: new Date(session.updatedAt)
|
|
2503
2618
|
}));
|
|
2504
2619
|
return {
|
|
2505
2620
|
threads,
|
|
2506
|
-
nextCursor: page.
|
|
2621
|
+
nextCursor: page.nextPageToken ?? void 0
|
|
2507
2622
|
};
|
|
2508
2623
|
},
|
|
2509
2624
|
async initialize(_threadId) {
|
|
2510
|
-
const session = await
|
|
2625
|
+
const session = await server.createSession({ agentName });
|
|
2511
2626
|
return { remoteId: session.id, externalId: void 0 };
|
|
2512
2627
|
},
|
|
2513
2628
|
async fetch(remoteId) {
|
|
2514
|
-
const session = await getSession(
|
|
2629
|
+
const session = await getSession(server, remoteId);
|
|
2515
2630
|
return {
|
|
2516
2631
|
status: "regular",
|
|
2517
2632
|
remoteId: session.id,
|
|
2518
|
-
title: session.title,
|
|
2633
|
+
title: session.title ?? void 0,
|
|
2519
2634
|
lastMessageAt: new Date(session.updatedAt)
|
|
2520
2635
|
};
|
|
2521
2636
|
},
|
|
@@ -2550,15 +2665,9 @@ function resolveTrueFoundryAgentConfig(options) {
|
|
|
2550
2665
|
}
|
|
2551
2666
|
function resolveTrueFoundryAgentRuntimeOptions(options) {
|
|
2552
2667
|
const agent = resolveTrueFoundryAgentConfig(options);
|
|
2553
|
-
if (agent.mode === "draft" && options.privateClient == null) {
|
|
2554
|
-
throw new Error(
|
|
2555
|
-
"Draft agent mode requires a `privateClient` PrivateAgentSessionClient."
|
|
2556
|
-
);
|
|
2557
|
-
}
|
|
2558
2668
|
return {
|
|
2559
2669
|
...options,
|
|
2560
|
-
agent
|
|
2561
|
-
privateClient: options.privateClient
|
|
2670
|
+
agent
|
|
2562
2671
|
};
|
|
2563
2672
|
}
|
|
2564
2673
|
|
|
@@ -2769,18 +2878,15 @@ import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMem
|
|
|
2769
2878
|
|
|
2770
2879
|
// src/loadSessionSnapshot.ts
|
|
2771
2880
|
var inflightBySessionId2 = /* @__PURE__ */ new Map();
|
|
2772
|
-
function loadSessionSnapshot(
|
|
2773
|
-
|
|
2774
|
-
let inflight = inflightBySessionId2.get(cacheKey);
|
|
2881
|
+
function loadSessionSnapshot(server, sessionId, onProgress) {
|
|
2882
|
+
let inflight = inflightBySessionId2.get(sessionId);
|
|
2775
2883
|
if (inflight == null) {
|
|
2776
|
-
inflight = getSession(
|
|
2777
|
-
(
|
|
2778
|
-
|
|
2779
|
-
if (inflightBySessionId2.get(cacheKey) === inflight) {
|
|
2780
|
-
inflightBySessionId2.delete(cacheKey);
|
|
2884
|
+
inflight = getSession(server, sessionId).then(() => buildSnapshotFromSessionEvents(server, sessionId, onProgress)).finally(() => {
|
|
2885
|
+
if (inflightBySessionId2.get(sessionId) === inflight) {
|
|
2886
|
+
inflightBySessionId2.delete(sessionId);
|
|
2781
2887
|
}
|
|
2782
2888
|
});
|
|
2783
|
-
inflightBySessionId2.set(
|
|
2889
|
+
inflightBySessionId2.set(sessionId, inflight);
|
|
2784
2890
|
}
|
|
2785
2891
|
return inflight;
|
|
2786
2892
|
}
|
|
@@ -2818,9 +2924,9 @@ function buildTurnInput(options) {
|
|
|
2818
2924
|
}
|
|
2819
2925
|
return [{ type: "user.message", content: options.userMessage ?? "" }];
|
|
2820
2926
|
}
|
|
2821
|
-
function bindAbort(
|
|
2927
|
+
function bindAbort(server, sessionId, abortSignal) {
|
|
2822
2928
|
const onAbort = () => {
|
|
2823
|
-
void
|
|
2929
|
+
void server.cancelSession({ sessionId }).catch(() => void 0);
|
|
2824
2930
|
};
|
|
2825
2931
|
if (abortSignal.aborted) {
|
|
2826
2932
|
onAbort();
|
|
@@ -2829,41 +2935,35 @@ function bindAbort(session, abortSignal) {
|
|
|
2829
2935
|
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
2830
2936
|
return onAbort;
|
|
2831
2937
|
}
|
|
2832
|
-
async function* streamTurnContent(
|
|
2833
|
-
const
|
|
2834
|
-
const turn = session.prepareTurn({
|
|
2835
|
-
input: buildTurnInput(options),
|
|
2836
|
-
...previousTurnId !== void 0 ? { previousTurnId } : {}
|
|
2837
|
-
});
|
|
2838
|
-
const onAbort = bindAbort(session, abortSignal);
|
|
2938
|
+
async function* streamTurnContent(server, sessionId, foldState, options, abortSignal, groupRootBaseline, onTurnIdAvailable) {
|
|
2939
|
+
const onAbort = bindAbort(server, sessionId, abortSignal);
|
|
2839
2940
|
if (abortSignal.aborted) {
|
|
2840
2941
|
return;
|
|
2841
2942
|
}
|
|
2842
2943
|
let turnIdNotified = false;
|
|
2843
|
-
const
|
|
2844
|
-
if (!turnIdNotified
|
|
2845
|
-
onTurnIdAvailable?.(
|
|
2944
|
+
const notifyTurnId = (turnId) => {
|
|
2945
|
+
if (!turnIdNotified) {
|
|
2946
|
+
onTurnIdAvailable?.(turnId);
|
|
2846
2947
|
turnIdNotified = true;
|
|
2847
2948
|
}
|
|
2848
2949
|
};
|
|
2950
|
+
const stream = server.prepareAndExecuteTurn({
|
|
2951
|
+
sessionId,
|
|
2952
|
+
input: buildTurnInput(options),
|
|
2953
|
+
previousTurnId: options.previousTurnId ?? "auto",
|
|
2954
|
+
abortSignal,
|
|
2955
|
+
...options.headers != null ? { headers: options.headers } : {}
|
|
2956
|
+
});
|
|
2849
2957
|
try {
|
|
2850
2958
|
for await (const update of streamTurnEvents(
|
|
2851
|
-
|
|
2852
|
-
{ stream: true },
|
|
2853
|
-
{
|
|
2854
|
-
abortSignal,
|
|
2855
|
-
...options.headers != null ? { headers: options.headers } : {}
|
|
2856
|
-
}
|
|
2857
|
-
),
|
|
2959
|
+
stream,
|
|
2858
2960
|
foldState,
|
|
2859
|
-
groupRootBaseline
|
|
2961
|
+
groupRootBaseline,
|
|
2962
|
+
notifyTurnId
|
|
2860
2963
|
)) {
|
|
2861
|
-
notifyTurnIdIfAvailable();
|
|
2862
2964
|
yield update;
|
|
2863
2965
|
}
|
|
2864
|
-
notifyTurnIdIfAvailable();
|
|
2865
2966
|
} catch (error) {
|
|
2866
|
-
notifyTurnIdIfAvailable();
|
|
2867
2967
|
if (error instanceof Error && error.name === "AbortError") {
|
|
2868
2968
|
return;
|
|
2869
2969
|
}
|
|
@@ -2872,9 +2972,14 @@ async function* streamTurnContent(session, foldState, options, abortSignal, grou
|
|
|
2872
2972
|
abortSignal.removeEventListener("abort", onAbort);
|
|
2873
2973
|
}
|
|
2874
2974
|
}
|
|
2875
|
-
async function* resumeTurnStream(
|
|
2975
|
+
async function* resumeTurnStream(server, sessionId, turnId, foldState, abortSignal, afterSequenceNumber, groupRootBaseline) {
|
|
2976
|
+
if (server.subscribeToTurn == null) {
|
|
2977
|
+
throw new Error(
|
|
2978
|
+
"resumeTurnStream requires AgentChatServer.subscribeToTurn"
|
|
2979
|
+
);
|
|
2980
|
+
}
|
|
2876
2981
|
const onAbort = () => {
|
|
2877
|
-
void
|
|
2982
|
+
void server.cancelSession({ sessionId }).catch(() => void 0);
|
|
2878
2983
|
};
|
|
2879
2984
|
if (abortSignal.aborted) {
|
|
2880
2985
|
onAbort();
|
|
@@ -2883,10 +2988,12 @@ async function* resumeTurnStream(turn, foldState, abortSignal, afterSequenceNumb
|
|
|
2883
2988
|
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
2884
2989
|
try {
|
|
2885
2990
|
yield* streamTurnEvents(
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2991
|
+
server.subscribeToTurn({
|
|
2992
|
+
sessionId,
|
|
2993
|
+
turnId,
|
|
2994
|
+
...afterSequenceNumber != null ? { afterSequenceNumber } : {},
|
|
2995
|
+
abortSignal
|
|
2996
|
+
}),
|
|
2890
2997
|
foldState,
|
|
2891
2998
|
groupRootBaseline
|
|
2892
2999
|
);
|
|
@@ -3022,20 +3129,15 @@ function resolveTurnInput(snapshot, turnId) {
|
|
|
3022
3129
|
return void 0;
|
|
3023
3130
|
}
|
|
3024
3131
|
function useTrueFoundryAgentMessages({
|
|
3025
|
-
|
|
3132
|
+
server,
|
|
3026
3133
|
sessionId,
|
|
3027
3134
|
isMain,
|
|
3028
3135
|
listEventsConcurrency,
|
|
3029
3136
|
onError,
|
|
3030
3137
|
initializeSession,
|
|
3031
3138
|
resolveConversationSessionId,
|
|
3032
|
-
privateClient,
|
|
3033
3139
|
getTurnHeaders
|
|
3034
3140
|
}) {
|
|
3035
|
-
const sessionOptions = useMemo2(
|
|
3036
|
-
() => privateClient != null ? { privateClient } : void 0,
|
|
3037
|
-
[privateClient]
|
|
3038
|
-
);
|
|
3039
3141
|
const [snapshot, setSnapshot] = useState2(createEmptySessionSnapshot);
|
|
3040
3142
|
const [isRunning, setIsRunning] = useState2(false);
|
|
3041
3143
|
const [isLoading, setIsLoading] = useState2(false);
|
|
@@ -3195,9 +3297,8 @@ function useTrueFoundryAgentMessages({
|
|
|
3195
3297
|
resolveConversationSessionIdRef.current
|
|
3196
3298
|
);
|
|
3197
3299
|
const loadedSnapshot = await loadSessionSnapshot(
|
|
3198
|
-
|
|
3300
|
+
server,
|
|
3199
3301
|
conversationSessionId,
|
|
3200
|
-
sessionOptions,
|
|
3201
3302
|
(snap) => {
|
|
3202
3303
|
if (generation === loadGenerationRef.current) {
|
|
3203
3304
|
setSnapshot(snap);
|
|
@@ -3216,7 +3317,9 @@ function useTrueFoundryAgentMessages({
|
|
|
3216
3317
|
const isContinuation = !extractTurnUserText(turn.input);
|
|
3217
3318
|
void runStream(
|
|
3218
3319
|
(signal) => resumeTurnStream(
|
|
3219
|
-
|
|
3320
|
+
server,
|
|
3321
|
+
conversationSessionId,
|
|
3322
|
+
turn.id,
|
|
3220
3323
|
loadedSnapshot.fold,
|
|
3221
3324
|
signal,
|
|
3222
3325
|
void 0,
|
|
@@ -3236,7 +3339,7 @@ function useTrueFoundryAgentMessages({
|
|
|
3236
3339
|
setIsLoading(false);
|
|
3237
3340
|
}
|
|
3238
3341
|
}
|
|
3239
|
-
}, [
|
|
3342
|
+
}, [server, runStream, sessionId, loadRetryTrigger, isMain]);
|
|
3240
3343
|
useEffect2(() => {
|
|
3241
3344
|
void load().catch(() => void 0);
|
|
3242
3345
|
}, [load]);
|
|
@@ -3255,7 +3358,6 @@ function useTrueFoundryAgentMessages({
|
|
|
3255
3358
|
activeSessionId,
|
|
3256
3359
|
resolveConversationSessionIdRef.current
|
|
3257
3360
|
);
|
|
3258
|
-
const session = await getSession(client, conversationSessionId, sessionOptions);
|
|
3259
3361
|
const turnHeaders = await getTurnHeadersRef.current?.();
|
|
3260
3362
|
const streamHeaders = turnHeaders != null ? { headers: turnHeaders } : {};
|
|
3261
3363
|
const isContinuation = "inputs" in options || "resumeMcpAuth" in options && options.resumeMcpAuth === true;
|
|
@@ -3316,7 +3418,8 @@ function useTrueFoundryAgentMessages({
|
|
|
3316
3418
|
(signal) => {
|
|
3317
3419
|
if ("inputs" in options) {
|
|
3318
3420
|
return streamTurnContent(
|
|
3319
|
-
|
|
3421
|
+
server,
|
|
3422
|
+
conversationSessionId,
|
|
3320
3423
|
snapshotRef.current.fold,
|
|
3321
3424
|
{ inputs: options.inputs, ...streamHeaders },
|
|
3322
3425
|
signal,
|
|
@@ -3325,7 +3428,8 @@ function useTrueFoundryAgentMessages({
|
|
|
3325
3428
|
}
|
|
3326
3429
|
if ("resumeMcpAuth" in options) {
|
|
3327
3430
|
return streamTurnContent(
|
|
3328
|
-
|
|
3431
|
+
server,
|
|
3432
|
+
conversationSessionId,
|
|
3329
3433
|
snapshotRef.current.fold,
|
|
3330
3434
|
{ resumeMcpAuth: true, ...streamHeaders },
|
|
3331
3435
|
signal,
|
|
@@ -3333,11 +3437,12 @@ function useTrueFoundryAgentMessages({
|
|
|
3333
3437
|
);
|
|
3334
3438
|
}
|
|
3335
3439
|
return streamTurnContent(
|
|
3336
|
-
|
|
3440
|
+
server,
|
|
3441
|
+
conversationSessionId,
|
|
3337
3442
|
snapshotRef.current.fold,
|
|
3338
3443
|
{
|
|
3339
3444
|
userMessage: options.userMessage,
|
|
3340
|
-
...options.previousTurnId !== void 0 ? { previousTurnId: options.previousTurnId } : isFirstTurnInSession ? { previousTurnId:
|
|
3445
|
+
...options.previousTurnId !== void 0 ? { previousTurnId: options.previousTurnId ?? "none" } : isFirstTurnInSession ? { previousTurnId: "none" } : {},
|
|
3341
3446
|
...streamHeaders
|
|
3342
3447
|
},
|
|
3343
3448
|
signal,
|
|
@@ -3363,7 +3468,7 @@ function useTrueFoundryAgentMessages({
|
|
|
3363
3468
|
isContinuation
|
|
3364
3469
|
);
|
|
3365
3470
|
},
|
|
3366
|
-
[
|
|
3471
|
+
[server, runStream, sessionId]
|
|
3367
3472
|
);
|
|
3368
3473
|
const cancel = useCallback2(async () => {
|
|
3369
3474
|
if (sessionId == null) {
|
|
@@ -3374,10 +3479,9 @@ function useTrueFoundryAgentMessages({
|
|
|
3374
3479
|
sessionId,
|
|
3375
3480
|
resolveConversationSessionIdRef.current
|
|
3376
3481
|
);
|
|
3377
|
-
|
|
3378
|
-
await session.cancel().catch(() => void 0);
|
|
3482
|
+
await server.cancelSession({ sessionId: conversationSessionId }).catch(() => void 0);
|
|
3379
3483
|
await activeRunRef.current?.catch(() => void 0);
|
|
3380
|
-
}, [
|
|
3484
|
+
}, [server, sessionId]);
|
|
3381
3485
|
const isRunningRef = useRef2(isRunning);
|
|
3382
3486
|
isRunningRef.current = isRunning;
|
|
3383
3487
|
const trySendCollectedRequiredActions = useCallback2(
|
|
@@ -3439,7 +3543,9 @@ function useTrueFoundryAgentMessages({
|
|
|
3439
3543
|
}
|
|
3440
3544
|
await runStream(
|
|
3441
3545
|
(signal) => resumeTurnStream(
|
|
3442
|
-
|
|
3546
|
+
server,
|
|
3547
|
+
turn.sessionId,
|
|
3548
|
+
turn.id,
|
|
3443
3549
|
snapshotRef.current.fold,
|
|
3444
3550
|
signal,
|
|
3445
3551
|
void 0,
|
|
@@ -3448,7 +3554,7 @@ function useTrueFoundryAgentMessages({
|
|
|
3448
3554
|
{ current: turn.id },
|
|
3449
3555
|
true
|
|
3450
3556
|
);
|
|
3451
|
-
}, [runStream]);
|
|
3557
|
+
}, [runStream, server]);
|
|
3452
3558
|
const branchFromTurn = useCallback2(
|
|
3453
3559
|
async (turnId, userMessage) => {
|
|
3454
3560
|
let activeSessionId = sessionId;
|
|
@@ -3462,13 +3568,14 @@ function useTrueFoundryAgentMessages({
|
|
|
3462
3568
|
activeSessionId,
|
|
3463
3569
|
resolveConversationSessionIdRef.current
|
|
3464
3570
|
);
|
|
3465
|
-
const session = await getSession(client, conversationSessionId, sessionOptions);
|
|
3466
3571
|
const previousTurnId = await resolveGatewayBranchPreviousTurnIdForTurn(
|
|
3467
|
-
|
|
3572
|
+
server,
|
|
3573
|
+
conversationSessionId,
|
|
3468
3574
|
turnId
|
|
3469
3575
|
);
|
|
3470
3576
|
const rewound = await buildSnapshotBeforeTurn(
|
|
3471
|
-
|
|
3577
|
+
server,
|
|
3578
|
+
conversationSessionId,
|
|
3472
3579
|
turnId,
|
|
3473
3580
|
listEventsConcurrency
|
|
3474
3581
|
);
|
|
@@ -3483,11 +3590,10 @@ function useTrueFoundryAgentMessages({
|
|
|
3483
3590
|
},
|
|
3484
3591
|
[
|
|
3485
3592
|
cancel,
|
|
3486
|
-
|
|
3593
|
+
server,
|
|
3487
3594
|
listEventsConcurrency,
|
|
3488
3595
|
sendTurn,
|
|
3489
|
-
sessionId
|
|
3490
|
-
sessionOptions
|
|
3596
|
+
sessionId
|
|
3491
3597
|
]
|
|
3492
3598
|
);
|
|
3493
3599
|
const resetFromTurn = useCallback2(
|
|
@@ -3543,13 +3649,9 @@ function useTrueFoundryAgentMessages({
|
|
|
3543
3649
|
sessionId,
|
|
3544
3650
|
resolveConversationSessionIdRef.current
|
|
3545
3651
|
);
|
|
3546
|
-
const session = await getSession(
|
|
3547
|
-
client,
|
|
3548
|
-
conversationSessionId,
|
|
3549
|
-
sessionOptions
|
|
3550
|
-
);
|
|
3551
3652
|
const next = await prependOlderSessionHistory(
|
|
3552
|
-
|
|
3653
|
+
server,
|
|
3654
|
+
conversationSessionId,
|
|
3553
3655
|
snapshotRef.current
|
|
3554
3656
|
);
|
|
3555
3657
|
if (generation !== loadGenerationRef.current) {
|
|
@@ -3570,7 +3672,7 @@ function useTrueFoundryAgentMessages({
|
|
|
3570
3672
|
})();
|
|
3571
3673
|
loadOlderInflightRef.current = run;
|
|
3572
3674
|
return run;
|
|
3573
|
-
}, [
|
|
3675
|
+
}, [server, isMain, sessionId]);
|
|
3574
3676
|
return {
|
|
3575
3677
|
messages,
|
|
3576
3678
|
isRunning,
|
|
@@ -3593,16 +3695,15 @@ function useTrueFoundryAgentMessages({
|
|
|
3593
3695
|
// src/useTrueFoundryAgentRuntime.ts
|
|
3594
3696
|
function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
|
|
3595
3697
|
const {
|
|
3596
|
-
|
|
3698
|
+
server,
|
|
3597
3699
|
agent,
|
|
3598
|
-
privateClient,
|
|
3599
3700
|
adapters,
|
|
3600
3701
|
onError,
|
|
3601
3702
|
listEventsConcurrency,
|
|
3602
3703
|
...sharedOptions
|
|
3603
3704
|
} = options;
|
|
3604
3705
|
const draftBridgeRef = useRef3(
|
|
3605
|
-
agent.mode === "draft"
|
|
3706
|
+
agent.mode === "draft" ? createDraftSessionBridge(server) : null
|
|
3606
3707
|
);
|
|
3607
3708
|
const draftSessionId = useAuiState(
|
|
3608
3709
|
(state) => agent.mode === "draft" ? state.threadListItem.remoteId ?? void 0 : void 0
|
|
@@ -3653,13 +3754,12 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
|
|
|
3653
3754
|
resetFromTurn,
|
|
3654
3755
|
retryLoad
|
|
3655
3756
|
} = useTrueFoundryAgentMessages({
|
|
3656
|
-
|
|
3757
|
+
server,
|
|
3657
3758
|
sessionId,
|
|
3658
3759
|
isMain,
|
|
3659
3760
|
listEventsConcurrency,
|
|
3660
3761
|
onError,
|
|
3661
3762
|
initializeSession,
|
|
3662
|
-
privateClient: agent.mode === "draft" ? privateClient : void 0,
|
|
3663
3763
|
getTurnHeaders: agent.mode === "draft" ? getTurnHeaders : void 0
|
|
3664
3764
|
});
|
|
3665
3765
|
if (agent.mode === "draft" && draftSpec.agentSpec != null) {
|
|
@@ -3681,9 +3781,9 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
|
|
|
3681
3781
|
);
|
|
3682
3782
|
const downloadSandboxFile = useCallback3(
|
|
3683
3783
|
async (path) => {
|
|
3684
|
-
if (
|
|
3784
|
+
if (server.downloadSandboxFile == null) {
|
|
3685
3785
|
const error = new Error(
|
|
3686
|
-
"Downloading a sandbox file requires
|
|
3786
|
+
"Downloading a sandbox file requires AgentChatServer.downloadSandboxFile."
|
|
3687
3787
|
);
|
|
3688
3788
|
onError?.(error);
|
|
3689
3789
|
throw error;
|
|
@@ -3693,10 +3793,9 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
|
|
|
3693
3793
|
onError?.(error);
|
|
3694
3794
|
throw error;
|
|
3695
3795
|
}
|
|
3696
|
-
|
|
3697
|
-
return await response.blob();
|
|
3796
|
+
return await server.downloadSandboxFile(sandboxId, { path });
|
|
3698
3797
|
},
|
|
3699
|
-
[
|
|
3798
|
+
[server, sandboxId, onError]
|
|
3700
3799
|
);
|
|
3701
3800
|
const draftExtras = useMemo3(() => {
|
|
3702
3801
|
if (agent.mode !== "draft") {
|
|
@@ -3781,7 +3880,7 @@ function useTrueFoundryAgentRuntimeImpl(options, pendingAgentSpecRef) {
|
|
|
3781
3880
|
}
|
|
3782
3881
|
function useTrueFoundryAgentRuntime(options) {
|
|
3783
3882
|
const resolved = resolveTrueFoundryAgentRuntimeOptions(options);
|
|
3784
|
-
const {
|
|
3883
|
+
const { server, agent } = resolved;
|
|
3785
3884
|
const pendingAgentSpecRef = useRef3(
|
|
3786
3885
|
agent.mode === "draft" ? agent.defaultAgentSpec : void 0
|
|
3787
3886
|
);
|
|
@@ -3789,23 +3888,18 @@ function useTrueFoundryAgentRuntime(options) {
|
|
|
3789
3888
|
const namedAgentName = agent.mode === "named" ? agent.agentName : void 0;
|
|
3790
3889
|
const threadListAdapter = useMemo3(() => {
|
|
3791
3890
|
if (agentMode === "draft") {
|
|
3792
|
-
if (privateClient == null) {
|
|
3793
|
-
throw new Error(
|
|
3794
|
-
"Draft agent mode requires a `privateClient` PrivateAgentSessionClient."
|
|
3795
|
-
);
|
|
3796
|
-
}
|
|
3797
3891
|
const draftAgent = agent;
|
|
3798
3892
|
return createTrueFoundryDraftThreadListAdapter({
|
|
3799
|
-
|
|
3893
|
+
server,
|
|
3800
3894
|
defaultAgentSpec: draftAgent.defaultAgentSpec,
|
|
3801
3895
|
getAgentSpec: () => pendingAgentSpecRef.current ?? draftAgent.defaultAgentSpec
|
|
3802
3896
|
});
|
|
3803
3897
|
}
|
|
3804
3898
|
return createTrueFoundryThreadListAdapter({
|
|
3805
|
-
|
|
3899
|
+
server,
|
|
3806
3900
|
agentName: namedAgentName
|
|
3807
3901
|
});
|
|
3808
|
-
}, [agentMode, namedAgentName,
|
|
3902
|
+
}, [agentMode, namedAgentName, server]);
|
|
3809
3903
|
return useRemoteThreadListRuntime({
|
|
3810
3904
|
allowNesting: true,
|
|
3811
3905
|
adapter: threadListAdapter,
|
|
@@ -3819,16 +3913,19 @@ function useTrueFoundryAgentRuntime(options) {
|
|
|
3819
3913
|
// src/truefoundryOwnedSessionsThreadListAdapter.ts
|
|
3820
3914
|
var THREAD_LIST_PAGE_SIZE3 = 20;
|
|
3821
3915
|
function ownedSessionTitle(session) {
|
|
3822
|
-
if (session.
|
|
3823
|
-
return draftSessionTitle(
|
|
3916
|
+
if (session.isMutable && session.agentSpec != null) {
|
|
3917
|
+
return draftSessionTitle({
|
|
3918
|
+
title: session.title,
|
|
3919
|
+
agentSpec: session.agentSpec
|
|
3920
|
+
});
|
|
3824
3921
|
}
|
|
3825
|
-
return session.title ?? session.agentName;
|
|
3922
|
+
return session.title ?? session.agentName ?? session.id;
|
|
3826
3923
|
}
|
|
3827
3924
|
function createTrueFoundryOwnedSessionsThreadListAdapter(options) {
|
|
3828
|
-
const {
|
|
3925
|
+
const { server } = options;
|
|
3829
3926
|
return {
|
|
3830
3927
|
async list({ after } = {}) {
|
|
3831
|
-
const page = await
|
|
3928
|
+
const page = await server.listSessions({
|
|
3832
3929
|
limit: THREAD_LIST_PAGE_SIZE3,
|
|
3833
3930
|
pageToken: after,
|
|
3834
3931
|
startTimestamp: sessionListStartTimestamp()
|
|
@@ -3841,7 +3938,7 @@ function createTrueFoundryOwnedSessionsThreadListAdapter(options) {
|
|
|
3841
3938
|
}));
|
|
3842
3939
|
return {
|
|
3843
3940
|
threads,
|
|
3844
|
-
nextCursor: page.
|
|
3941
|
+
nextCursor: page.nextPageToken ?? void 0
|
|
3845
3942
|
};
|
|
3846
3943
|
},
|
|
3847
3944
|
async initialize() {
|
|
@@ -3850,14 +3947,12 @@ function createTrueFoundryOwnedSessionsThreadListAdapter(options) {
|
|
|
3850
3947
|
);
|
|
3851
3948
|
},
|
|
3852
3949
|
async fetch(remoteId) {
|
|
3853
|
-
const
|
|
3854
|
-
draftSessionId: remoteId
|
|
3855
|
-
});
|
|
3950
|
+
const session = await server.getSession({ sessionId: remoteId });
|
|
3856
3951
|
return {
|
|
3857
3952
|
status: "regular",
|
|
3858
|
-
remoteId:
|
|
3859
|
-
title:
|
|
3860
|
-
lastMessageAt: new Date(
|
|
3953
|
+
remoteId: session.id,
|
|
3954
|
+
title: ownedSessionTitle(session),
|
|
3955
|
+
lastMessageAt: new Date(session.updatedAt)
|
|
3861
3956
|
};
|
|
3862
3957
|
},
|
|
3863
3958
|
async rename() {
|
|
@@ -3874,9 +3969,6 @@ function createTrueFoundryOwnedSessionsThreadListAdapter(options) {
|
|
|
3874
3969
|
};
|
|
3875
3970
|
}
|
|
3876
3971
|
|
|
3877
|
-
// src/index.ts
|
|
3878
|
-
import { PrivateAgentSessionClient } from "truefoundry-gateway-sdk/agents/private";
|
|
3879
|
-
|
|
3880
3972
|
// src/hooks.ts
|
|
3881
3973
|
import { useMemo as useMemo4 } from "react";
|
|
3882
3974
|
import { useAui as useAui2 } from "@assistant-ui/store";
|
|
@@ -4021,7 +4113,6 @@ var trueFoundryAttachmentAdapter = {
|
|
|
4021
4113
|
}
|
|
4022
4114
|
};
|
|
4023
4115
|
export {
|
|
4024
|
-
PrivateAgentSessionClient,
|
|
4025
4116
|
ROOT_THREAD_ID,
|
|
4026
4117
|
TOOL_RESPONSE_THREAD_ID_CUSTOM_KEY,
|
|
4027
4118
|
buildEditedUserMessageContent,
|
|
@@ -4039,7 +4130,9 @@ export {
|
|
|
4039
4130
|
findPausedAssistantMessage,
|
|
4040
4131
|
getSession,
|
|
4041
4132
|
getTurnMessageContent,
|
|
4133
|
+
isEventDelta,
|
|
4042
4134
|
mergeAgentSpec,
|
|
4135
|
+
mergeEventDelta,
|
|
4043
4136
|
messageHasPendingApprovals,
|
|
4044
4137
|
messageHasPendingRequiredActions,
|
|
4045
4138
|
messageHasPendingResponses,
|