@truefoundry/assistant-ui-runtime 0.1.0-rc.1 → 0.1.2
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 +45 -77
- package/dist/index.d.ts +14 -2
- package/dist/index.js +697 -147
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/agentSessionModule.d.ts +14 -2
- package/src/convertTurnMessages.test.ts +502 -1
- package/src/convertTurnMessages.ts +471 -28
- package/src/createSubAgent.ts +13 -5
- package/src/draftAgentConfig.test.ts +1 -1
- package/src/foldPeerThreads.test.ts +56 -0
- package/src/foldPeerThreads.ts +7 -1
- package/src/hooks.ts +24 -0
- package/src/index.ts +7 -5
- package/src/loadSessionSnapshot.test.ts +21 -6
- package/src/loadSessionSnapshot.ts +9 -5
- package/src/{bindDraftAgentSession.test.ts → private/bindDraftAgentSession.test.ts} +3 -2
- package/src/{draftSessionBridge.ts → private/draftSessionBridge.ts} +8 -2
- package/src/{truefoundryDraftThreadListAdapter.ts → private/truefoundryDraftThreadListAdapter.ts} +1 -1
- package/src/private/useDraftAgentSpec.test.tsx +153 -0
- package/src/{useDraftAgentSpec.ts → private/useDraftAgentSpec.ts} +80 -3
- package/src/sessionSnapshot.ts +48 -2
- package/src/sessions.ts +1 -1
- package/src/streamTurn.test.ts +34 -0
- package/src/streamTurn.ts +9 -1
- package/src/truefoundryExtras.ts +5 -1
- package/src/types.ts +1 -1
- package/src/useTrueFoundryAgentMessages.test.tsx +275 -1
- package/src/useTrueFoundryAgentMessages.ts +263 -70
- package/src/useTrueFoundryAgentRuntime.ts +51 -13
- /package/src/{agentSpec.ts → private/agentSpec.ts} +0 -0
- /package/src/{bindDraftAgentSession.ts → private/bindDraftAgentSession.ts} +0 -0
- /package/src/{truefoundryDraftThreadListAdapter.test.ts → private/truefoundryDraftThreadListAdapter.test.ts} +0 -0
|
@@ -14,7 +14,7 @@ import { useAui, useAuiState } from "@assistant-ui/store";
|
|
|
14
14
|
import type { MutableRefObject } from "react";
|
|
15
15
|
import { useCallback, useMemo, useRef, useState } from "react";
|
|
16
16
|
|
|
17
|
-
import type { AgentSpec } from "./agentSpec.js";
|
|
17
|
+
import type { AgentSpec } from "./private/agentSpec.js";
|
|
18
18
|
import {
|
|
19
19
|
collectPendingApprovals,
|
|
20
20
|
collectPendingToolResponses,
|
|
@@ -26,14 +26,17 @@ import {
|
|
|
26
26
|
extractEditedText,
|
|
27
27
|
parseTurnIdFromMessageId,
|
|
28
28
|
} from "./convertTurnMessages.js";
|
|
29
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
createDraftSessionBridge,
|
|
31
|
+
DRAFT_SESSION_LAST_UPDATED_AT_HEADER,
|
|
32
|
+
} from "./private/draftSessionBridge.js";
|
|
30
33
|
import { MCP_AUTH_RESUME_RUN_CUSTOM_KEY } from "./mcpAuth.js";
|
|
31
|
-
import { createTrueFoundryDraftThreadListAdapter } from "./truefoundryDraftThreadListAdapter.js";
|
|
34
|
+
import { createTrueFoundryDraftThreadListAdapter } from "./private/truefoundryDraftThreadListAdapter.js";
|
|
32
35
|
import { trueFoundryExtras } from "./truefoundryExtras.js";
|
|
33
36
|
import { createTrueFoundryThreadListAdapter } from "./truefoundryThreadListAdapter.js";
|
|
34
37
|
import type { UseTrueFoundryAgentRuntimeOptions } from "./types.js";
|
|
35
38
|
import { resolveTrueFoundryAgentRuntimeOptions } from "./types.js";
|
|
36
|
-
import { useDraftAgentSpec } from "./useDraftAgentSpec.js";
|
|
39
|
+
import { useDraftAgentSpec } from "./private/useDraftAgentSpec.js";
|
|
37
40
|
import { useTrueFoundryAgentMessages } from "./useTrueFoundryAgentMessages.js";
|
|
38
41
|
|
|
39
42
|
function useTrueFoundryAgentRuntimeImpl(
|
|
@@ -63,6 +66,9 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
63
66
|
: undefined,
|
|
64
67
|
);
|
|
65
68
|
const sessionId = useAuiState((state) => state.threadListItem.remoteId ?? undefined);
|
|
69
|
+
const isMain = useAuiState(
|
|
70
|
+
(state) => state.threads.mainThreadId === state.threadListItem.id,
|
|
71
|
+
);
|
|
66
72
|
|
|
67
73
|
const draftSpec = useDraftAgentSpec({
|
|
68
74
|
draftSessionId,
|
|
@@ -73,6 +79,20 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
73
79
|
onError,
|
|
74
80
|
});
|
|
75
81
|
|
|
82
|
+
const takeTurnHeaderTimestampRef = useRef(draftSpec.takeTurnHeaderTimestamp);
|
|
83
|
+
takeTurnHeaderTimestampRef.current = draftSpec.takeTurnHeaderTimestamp;
|
|
84
|
+
|
|
85
|
+
const getTurnHeaders = useCallback(async () => {
|
|
86
|
+
if (agent.mode !== "draft") {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
const updatedAt = await takeTurnHeaderTimestampRef.current();
|
|
90
|
+
if (updatedAt == null) {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
return { [DRAFT_SESSION_LAST_UPDATED_AT_HEADER]: updatedAt };
|
|
94
|
+
}, [agent.mode]);
|
|
95
|
+
|
|
76
96
|
const aui = useAui();
|
|
77
97
|
const initializeSession = useCallback(
|
|
78
98
|
() => aui.threadListItem().initialize(),
|
|
@@ -87,6 +107,9 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
87
107
|
messages,
|
|
88
108
|
isRunning,
|
|
89
109
|
isLoading,
|
|
110
|
+
isLoadingOlderHistory,
|
|
111
|
+
hasOlderHistory,
|
|
112
|
+
loadOlderHistory,
|
|
90
113
|
sendTurn,
|
|
91
114
|
cancel,
|
|
92
115
|
respondToToolApproval,
|
|
@@ -94,13 +117,16 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
94
117
|
resumeRun,
|
|
95
118
|
editFromTurn,
|
|
96
119
|
resetFromTurn,
|
|
120
|
+
retryLoad,
|
|
97
121
|
} = useTrueFoundryAgentMessages({
|
|
98
122
|
client,
|
|
99
123
|
sessionId,
|
|
124
|
+
isMain,
|
|
100
125
|
listEventsConcurrency,
|
|
101
126
|
onError,
|
|
102
127
|
initializeSession,
|
|
103
128
|
draftGateway: agent.mode === "draft" ? gateway : undefined,
|
|
129
|
+
getTurnHeaders: agent.mode === "draft" ? getTurnHeaders : undefined,
|
|
104
130
|
});
|
|
105
131
|
|
|
106
132
|
if (agent.mode === "draft" && draftSpec.agentSpec != null) {
|
|
@@ -175,6 +201,10 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
175
201
|
resetFromTurn(turnId).catch((error) => {
|
|
176
202
|
onError?.(error);
|
|
177
203
|
}),
|
|
204
|
+
reload: retryLoad,
|
|
205
|
+
hasOlderHistory,
|
|
206
|
+
isLoadingOlderHistory,
|
|
207
|
+
loadOlderHistory,
|
|
178
208
|
draft: draftExtras,
|
|
179
209
|
}),
|
|
180
210
|
unstable_enableToolInvocations: true,
|
|
@@ -228,34 +258,42 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
228
258
|
}
|
|
229
259
|
|
|
230
260
|
export function useTrueFoundryAgentRuntime(options: UseTrueFoundryAgentRuntimeOptions) {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
261
|
+
// resolveTrueFoundryAgentRuntimeOptions is a cheap pure function; memoizing on the
|
|
262
|
+
// whole `options` object (which callers typically pass as an inline literal) means
|
|
263
|
+
// `resolved` — and everything derived from it — would be recreated on every render,
|
|
264
|
+
// causing `threadListAdapter` to be a new object each render. We compute `resolved`
|
|
265
|
+
// unconditionally and stabilize individual downstream values with primitives/refs.
|
|
266
|
+
const resolved = resolveTrueFoundryAgentRuntimeOptions(options);
|
|
235
267
|
const { client, agent, gateway } = resolved;
|
|
236
268
|
|
|
237
269
|
const pendingAgentSpecRef = useRef<AgentSpec | undefined>(
|
|
238
270
|
agent.mode === "draft" ? agent.defaultAgentSpec : undefined,
|
|
239
271
|
);
|
|
240
272
|
|
|
273
|
+
// Use stable primitive deps so that threadListAdapter is not recreated every render
|
|
274
|
+
// when options is an inline object literal (new reference on every parent render).
|
|
275
|
+
const agentMode = agent.mode;
|
|
276
|
+
const namedAgentName = agent.mode === "named" ? agent.agentName : undefined;
|
|
241
277
|
const threadListAdapter = useMemo(() => {
|
|
242
|
-
if (
|
|
278
|
+
if (agentMode === "draft") {
|
|
243
279
|
if (gateway == null) {
|
|
244
280
|
throw new Error(
|
|
245
281
|
"Draft agent mode requires a `gateway` TrueFoundryGateway client.",
|
|
246
282
|
);
|
|
247
283
|
}
|
|
284
|
+
const draftAgent = agent as Extract<typeof agent, { mode: "draft" }>;
|
|
248
285
|
return createTrueFoundryDraftThreadListAdapter({
|
|
249
286
|
gateway,
|
|
250
|
-
defaultAgentSpec:
|
|
251
|
-
getAgentSpec: () => pendingAgentSpecRef.current ??
|
|
287
|
+
defaultAgentSpec: draftAgent.defaultAgentSpec,
|
|
288
|
+
getAgentSpec: () => pendingAgentSpecRef.current ?? draftAgent.defaultAgentSpec,
|
|
252
289
|
});
|
|
253
290
|
}
|
|
254
291
|
return createTrueFoundryThreadListAdapter({
|
|
255
292
|
client,
|
|
256
|
-
agentName:
|
|
293
|
+
agentName: namedAgentName!,
|
|
257
294
|
});
|
|
258
|
-
|
|
295
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
296
|
+
}, [agentMode, namedAgentName, client, gateway]);
|
|
259
297
|
|
|
260
298
|
return useRemoteThreadListRuntime({
|
|
261
299
|
allowNesting: true,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|