@truefoundry/assistant-ui-runtime 0.1.5 → 0.1.6
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 +198 -401
- package/dist/chunk-3A2EPLQG.js +93 -0
- package/dist/chunk-3A2EPLQG.js.map +1 -0
- package/dist/chunk-Q2SHKMLM.js +270 -0
- package/dist/chunk-Q2SHKMLM.js.map +1 -0
- package/dist/index.d.ts +24 -29
- package/dist/index.js +264 -237
- package/dist/index.js.map +1 -1
- package/dist/plugins/truefoundry-agent-server-adapter/index.d.ts +162 -0
- package/dist/plugins/truefoundry-agent-server-adapter/index.js +19 -0
- package/dist/plugins/truefoundry-agent-server-adapter/index.js.map +1 -0
- package/dist/server/index.d.ts +17 -0
- package/dist/server/index.js +9 -0
- package/dist/server/index.js.map +1 -0
- package/dist/types-BfiFf8O1.d.ts +468 -0
- package/package.json +19 -6
- package/src/askUserQuestion.ts +3 -3
- package/src/buildEditedUserMessageContent.test.ts +2 -2
- package/src/collectPending.ts +1 -1
- package/src/convertTurnMessages.test.ts +141 -196
- package/src/convertTurnMessages.ts +130 -76
- 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 +80 -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/README.md +178 -0
- package/src/plugins/truefoundry-agent-server-adapter/guards.test.ts +113 -0
- package/src/plugins/truefoundry-agent-server-adapter/guards.ts +130 -0
- package/src/plugins/truefoundry-agent-server-adapter/index.ts +359 -0
- package/src/plugins/truefoundry-agent-server-adapter/types.ts +135 -0
- package/src/plugins/truefoundry-agent-server-adapter/types.typecheck.ts +164 -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 +319 -0
- package/src/sessionSnapshot.ts +1 -1
- package/src/sessions.ts +5 -21
- package/src/streamTurn.test.ts +172 -155
- package/src/streamTurn.ts +51 -48
- 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 +7 -7
- package/src/turnEventHelpers.ts +1 -1
- package/src/types.ts +2 -16
- package/src/useTrueFoundryAgentMessages.test.tsx +38 -70
- package/src/useTrueFoundryAgentMessages.ts +32 -44
- 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
|
@@ -44,9 +44,8 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
44
44
|
pendingAgentSpecRef: MutableRefObject<AgentSpec | undefined>,
|
|
45
45
|
) {
|
|
46
46
|
const {
|
|
47
|
-
|
|
47
|
+
server,
|
|
48
48
|
agent,
|
|
49
|
-
privateClient,
|
|
50
49
|
adapters,
|
|
51
50
|
onError,
|
|
52
51
|
listEventsConcurrency,
|
|
@@ -54,9 +53,7 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
54
53
|
} = options;
|
|
55
54
|
|
|
56
55
|
const draftBridgeRef = useRef(
|
|
57
|
-
agent.mode === "draft"
|
|
58
|
-
? createDraftSessionBridge(privateClient)
|
|
59
|
-
: null,
|
|
56
|
+
agent.mode === "draft" ? createDraftSessionBridge(server) : null,
|
|
60
57
|
);
|
|
61
58
|
|
|
62
59
|
const draftSessionId = useAuiState(
|
|
@@ -119,13 +116,12 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
119
116
|
resetFromTurn,
|
|
120
117
|
retryLoad,
|
|
121
118
|
} = useTrueFoundryAgentMessages({
|
|
122
|
-
|
|
119
|
+
server,
|
|
123
120
|
sessionId,
|
|
124
121
|
isMain,
|
|
125
122
|
listEventsConcurrency,
|
|
126
123
|
onError,
|
|
127
124
|
initializeSession,
|
|
128
|
-
privateClient: agent.mode === "draft" ? privateClient : undefined,
|
|
129
125
|
getTurnHeaders: agent.mode === "draft" ? getTurnHeaders : undefined,
|
|
130
126
|
});
|
|
131
127
|
|
|
@@ -151,9 +147,9 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
151
147
|
|
|
152
148
|
const downloadSandboxFile = useCallback(
|
|
153
149
|
async (path: string) => {
|
|
154
|
-
if (
|
|
150
|
+
if (server.downloadSandboxFile == null) {
|
|
155
151
|
const error = new Error(
|
|
156
|
-
"Downloading a sandbox file requires
|
|
152
|
+
"Downloading a sandbox file requires AgentChatServer.downloadSandboxFile.",
|
|
157
153
|
);
|
|
158
154
|
onError?.(error);
|
|
159
155
|
throw error;
|
|
@@ -163,10 +159,9 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
163
159
|
onError?.(error);
|
|
164
160
|
throw error;
|
|
165
161
|
}
|
|
166
|
-
|
|
167
|
-
return await response.blob();
|
|
162
|
+
return await server.downloadSandboxFile(sandboxId, { path });
|
|
168
163
|
},
|
|
169
|
-
[
|
|
164
|
+
[server, sandboxId, onError],
|
|
170
165
|
);
|
|
171
166
|
|
|
172
167
|
const draftExtras = useMemo(() => {
|
|
@@ -258,42 +253,30 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
258
253
|
}
|
|
259
254
|
|
|
260
255
|
export function useTrueFoundryAgentRuntime(options: UseTrueFoundryAgentRuntimeOptions) {
|
|
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
256
|
const resolved = resolveTrueFoundryAgentRuntimeOptions(options);
|
|
267
|
-
const {
|
|
257
|
+
const { server, agent } = resolved;
|
|
268
258
|
|
|
269
259
|
const pendingAgentSpecRef = useRef<AgentSpec | undefined>(
|
|
270
260
|
agent.mode === "draft" ? agent.defaultAgentSpec : undefined,
|
|
271
261
|
);
|
|
272
262
|
|
|
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
263
|
const agentMode = agent.mode;
|
|
276
264
|
const namedAgentName = agent.mode === "named" ? agent.agentName : undefined;
|
|
277
265
|
const threadListAdapter = useMemo(() => {
|
|
278
266
|
if (agentMode === "draft") {
|
|
279
|
-
if (privateClient == null) {
|
|
280
|
-
throw new Error(
|
|
281
|
-
"Draft agent mode requires a `privateClient` PrivateAgentSessionClient.",
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
267
|
const draftAgent = agent as Extract<typeof agent, { mode: "draft" }>;
|
|
285
268
|
return createTrueFoundryDraftThreadListAdapter({
|
|
286
|
-
|
|
269
|
+
server,
|
|
287
270
|
defaultAgentSpec: draftAgent.defaultAgentSpec,
|
|
288
271
|
getAgentSpec: () => pendingAgentSpecRef.current ?? draftAgent.defaultAgentSpec,
|
|
289
272
|
});
|
|
290
273
|
}
|
|
291
274
|
return createTrueFoundryThreadListAdapter({
|
|
292
|
-
|
|
275
|
+
server,
|
|
293
276
|
agentName: namedAgentName!,
|
|
294
277
|
});
|
|
295
278
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
296
|
-
}, [agentMode, namedAgentName,
|
|
279
|
+
}, [agentMode, namedAgentName, server]);
|
|
297
280
|
|
|
298
281
|
return useRemoteThreadListRuntime({
|
|
299
282
|
allowNesting: true,
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
import type { PrivateAgentSessionClient } from "truefoundry-gateway-sdk/agents/private";
|
|
4
|
-
|
|
5
|
-
import { bindDraftAgentSession } from "./bindDraftAgentSession.js";
|
|
6
|
-
|
|
7
|
-
const draft = {
|
|
8
|
-
type: "session/draft" as const,
|
|
9
|
-
id: "draft-1",
|
|
10
|
-
agentSpec: { model: { name: "anthropic/claude-sonnet-4-6" } },
|
|
11
|
-
createdBySubject: { type: "user" as const, id: "u1" },
|
|
12
|
-
createdAt: "2026-06-30T10:00:00.000Z",
|
|
13
|
-
updatedAt: "2026-06-30T10:00:00.000Z",
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
describe("bindDraftAgentSession", () => {
|
|
17
|
-
it("validates the draft and binds turns to the draft session id", async () => {
|
|
18
|
-
const getDraftSession = vi.fn().mockResolvedValue(draft);
|
|
19
|
-
const privateClient = {
|
|
20
|
-
getDraftSession,
|
|
21
|
-
} as unknown as PrivateAgentSessionClient;
|
|
22
|
-
|
|
23
|
-
const session = await bindDraftAgentSession(privateClient, "draft-1");
|
|
24
|
-
|
|
25
|
-
expect(getDraftSession).toHaveBeenCalledWith({ draftSessionId: "draft-1" });
|
|
26
|
-
expect(session.id).toBe("draft-1");
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe("createDraftSessionBridge", () => {
|
|
31
|
-
it("syncs agent spec via draftSessions.update and returns updatedAt", async () => {
|
|
32
|
-
const { createDraftSessionBridge } = await import("./draftSessionBridge.js");
|
|
33
|
-
const update = vi.fn().mockResolvedValue({ data: draft });
|
|
34
|
-
const getDraftSession = vi.fn().mockResolvedValue(draft);
|
|
35
|
-
const privateClient = {
|
|
36
|
-
getDraftSession,
|
|
37
|
-
client: {
|
|
38
|
-
agents: {
|
|
39
|
-
private: {
|
|
40
|
-
draftSessions: { update },
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
} as unknown as PrivateAgentSessionClient;
|
|
45
|
-
|
|
46
|
-
const bridge = createDraftSessionBridge(privateClient);
|
|
47
|
-
const updatedAt = await bridge.syncAgentSpec("draft-1", draft.agentSpec);
|
|
48
|
-
|
|
49
|
-
expect(update).toHaveBeenCalledWith("draft-1", {
|
|
50
|
-
agentSpec: draft.agentSpec,
|
|
51
|
-
});
|
|
52
|
-
expect(updatedAt).toBe(draft.updatedAt);
|
|
53
|
-
});
|
|
54
|
-
});
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { AgentSession } from "truefoundry-gateway-sdk/agents";
|
|
2
|
-
import type { PrivateAgentSessionClient } from "truefoundry-gateway-sdk/agents/private";
|
|
3
|
-
|
|
4
|
-
const inflightByDraftId = new Map<string, Promise<AgentSession>>();
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Binds turn APIs for a draft session via `PrivateAgentSessionClient.getDraftSession`.
|
|
8
|
-
* Returns an `AgentDraftSession` (identical turn surface to `AgentSession`).
|
|
9
|
-
*/
|
|
10
|
-
export async function bindDraftAgentSession(
|
|
11
|
-
privateClient: PrivateAgentSessionClient,
|
|
12
|
-
draftSessionId: string,
|
|
13
|
-
): Promise<AgentSession> {
|
|
14
|
-
let inflight = inflightByDraftId.get(draftSessionId);
|
|
15
|
-
if (inflight == null) {
|
|
16
|
-
inflight = privateClient
|
|
17
|
-
.getDraftSession({ draftSessionId })
|
|
18
|
-
// AgentDraftSession shares the turn API with AgentSession.
|
|
19
|
-
.then((draft) => draft as unknown as AgentSession)
|
|
20
|
-
.finally(() => {
|
|
21
|
-
if (inflightByDraftId.get(draftSessionId) === inflight) {
|
|
22
|
-
inflightByDraftId.delete(draftSessionId);
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
inflightByDraftId.set(draftSessionId, inflight);
|
|
26
|
-
}
|
|
27
|
-
return inflight;
|
|
28
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { TrueFoundryGateway } from "truefoundry-gateway-sdk";
|
|
2
|
-
import type { PrivateAgentSessionClient } from "truefoundry-gateway-sdk/agents/private";
|
|
3
|
-
|
|
4
|
-
/** Reach the underlying gateway for APIs not yet wrapped on PrivateAgentSessionClient (update, sandbox download). */
|
|
5
|
-
export function getGatewayFromPrivateClient(
|
|
6
|
-
privateClient: PrivateAgentSessionClient,
|
|
7
|
-
): TrueFoundryGateway {
|
|
8
|
-
const internal = privateClient as unknown as { client: TrueFoundryGateway };
|
|
9
|
-
if (internal.client == null) {
|
|
10
|
-
throw new Error("PrivateAgentSessionClient is missing an internal gateway client.");
|
|
11
|
-
}
|
|
12
|
-
return internal.client;
|
|
13
|
-
}
|