@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.
Files changed (70) hide show
  1. package/README.md +198 -401
  2. package/dist/chunk-3A2EPLQG.js +93 -0
  3. package/dist/chunk-3A2EPLQG.js.map +1 -0
  4. package/dist/chunk-Q2SHKMLM.js +270 -0
  5. package/dist/chunk-Q2SHKMLM.js.map +1 -0
  6. package/dist/index.d.ts +24 -29
  7. package/dist/index.js +264 -237
  8. package/dist/index.js.map +1 -1
  9. package/dist/plugins/truefoundry-agent-server-adapter/index.d.ts +162 -0
  10. package/dist/plugins/truefoundry-agent-server-adapter/index.js +19 -0
  11. package/dist/plugins/truefoundry-agent-server-adapter/index.js.map +1 -0
  12. package/dist/server/index.d.ts +17 -0
  13. package/dist/server/index.js +9 -0
  14. package/dist/server/index.js.map +1 -0
  15. package/dist/types-BfiFf8O1.d.ts +468 -0
  16. package/package.json +19 -6
  17. package/src/askUserQuestion.ts +3 -3
  18. package/src/buildEditedUserMessageContent.test.ts +2 -2
  19. package/src/collectPending.ts +1 -1
  20. package/src/convertTurnMessages.test.ts +141 -196
  21. package/src/convertTurnMessages.ts +130 -76
  22. package/src/createSubAgent.ts +1 -1
  23. package/src/draftAgentConfig.test.ts +26 -29
  24. package/src/extractTurnUserText.ts +1 -1
  25. package/src/foldPeerThreads.test.ts +1 -1
  26. package/src/foldPeerThreads.ts +3 -2
  27. package/src/index.ts +80 -4
  28. package/src/listPages.ts +21 -0
  29. package/src/loadSessionSnapshot.test.ts +9 -8
  30. package/src/loadSessionSnapshot.ts +9 -14
  31. package/src/mcpAuth.ts +6 -3
  32. package/src/messageCustomMetadata.ts +1 -1
  33. package/src/modelMessageContent.ts +1 -1
  34. package/src/modelMessageImageContent.test.ts +1 -1
  35. package/src/modelMessageImageContent.ts +7 -6
  36. package/src/plugins/truefoundry-agent-server-adapter/README.md +178 -0
  37. package/src/plugins/truefoundry-agent-server-adapter/guards.test.ts +113 -0
  38. package/src/plugins/truefoundry-agent-server-adapter/guards.ts +130 -0
  39. package/src/plugins/truefoundry-agent-server-adapter/index.ts +359 -0
  40. package/src/plugins/truefoundry-agent-server-adapter/types.ts +135 -0
  41. package/src/plugins/truefoundry-agent-server-adapter/types.typecheck.ts +164 -0
  42. package/src/private/agentSpec.ts +8 -3
  43. package/src/private/draftSessionBridge.ts +14 -13
  44. package/src/private/truefoundryDraftThreadListAdapter.test.ts +44 -49
  45. package/src/private/truefoundryDraftThreadListAdapter.ts +22 -16
  46. package/src/requiredActionInputs.ts +1 -1
  47. package/src/requiredActionsFromActiveUpdate.test.ts +1 -1
  48. package/src/server/eventUtils.ts +120 -0
  49. package/src/server/events.ts +246 -0
  50. package/src/server/index.ts +66 -0
  51. package/src/server/types.ts +319 -0
  52. package/src/sessionSnapshot.ts +1 -1
  53. package/src/sessions.ts +5 -21
  54. package/src/streamTurn.test.ts +172 -155
  55. package/src/streamTurn.ts +51 -48
  56. package/src/toolApproval.ts +4 -4
  57. package/src/toolResponse.ts +4 -4
  58. package/src/truefoundryExtras.ts +1 -1
  59. package/src/truefoundryOwnedSessionsThreadListAdapter.test.ts +26 -29
  60. package/src/truefoundryOwnedSessionsThreadListAdapter.ts +18 -23
  61. package/src/truefoundryThreadListAdapter.test.ts +16 -18
  62. package/src/truefoundryThreadListAdapter.ts +7 -7
  63. package/src/turnEventHelpers.ts +1 -1
  64. package/src/types.ts +2 -16
  65. package/src/useTrueFoundryAgentMessages.test.tsx +38 -70
  66. package/src/useTrueFoundryAgentMessages.ts +32 -44
  67. package/src/useTrueFoundryAgentRuntime.ts +11 -28
  68. package/src/private/bindDraftAgentSession.test.ts +0 -54
  69. package/src/private/bindDraftAgentSession.ts +0 -28
  70. 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
- client,
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" && privateClient != null
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
- client,
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 (privateClient == null) {
150
+ if (server.downloadSandboxFile == null) {
155
151
  const error = new Error(
156
- "Downloading a sandbox file requires a `privateClient` PrivateAgentSessionClient.",
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
- const response = await privateClient.downloadSandboxFile(sandboxId, { path });
167
- return await response.blob();
162
+ return await server.downloadSandboxFile(sandboxId, { path });
168
163
  },
169
- [privateClient, sandboxId, onError],
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 { client, agent, privateClient } = resolved;
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
- privateClient,
269
+ server,
287
270
  defaultAgentSpec: draftAgent.defaultAgentSpec,
288
271
  getAgentSpec: () => pendingAgentSpecRef.current ?? draftAgent.defaultAgentSpec,
289
272
  });
290
273
  }
291
274
  return createTrueFoundryThreadListAdapter({
292
- client,
275
+ server,
293
276
  agentName: namedAgentName!,
294
277
  });
295
278
  // eslint-disable-next-line react-hooks/exhaustive-deps
296
- }, [agentMode, namedAgentName, client, privateClient]);
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
- }