@truefoundry/assistant-ui-runtime 0.1.3-rc.2 → 0.1.4
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 +15 -14
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/convertTurnMessages.test.ts +10 -10
- package/src/draftAgentConfig.test.ts +7 -7
- package/src/foldPeerThreads.test.ts +1 -1
- package/src/modelMessageImageContent.ts +3 -1
- package/src/private/truefoundryDraftThreadListAdapter.test.ts +1 -1
- package/src/streamTurn.test.ts +91 -3
- package/src/streamTurn.ts +29 -16
- package/src/useTrueFoundryAgentMessages.ts +10 -1
- package/src/useTrueFoundryAgentRuntime.ts +1 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truefoundry/assistant-ui-runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "TrueFoundry Gateway agent runtime adapter for assistant-ui",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"@types/react": "*",
|
|
52
52
|
"react": "^18 || ^19",
|
|
53
|
-
"truefoundry-gateway-sdk": "^0.
|
|
53
|
+
"truefoundry-gateway-sdk": "^0.4.0-rc.1"
|
|
54
54
|
},
|
|
55
55
|
"peerDependenciesMeta": {
|
|
56
56
|
"@types/react": {
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"@types/react": "^19.2.17",
|
|
64
64
|
"jsdom": "^29.1.1",
|
|
65
65
|
"react": "^19.2.4",
|
|
66
|
-
"truefoundry-gateway-sdk": "0.
|
|
66
|
+
"truefoundry-gateway-sdk": "0.4.0-rc.1",
|
|
67
67
|
"tsup": "^8.5.0",
|
|
68
68
|
"typescript": "^5.9.3",
|
|
69
69
|
"vitest": "^4.1.9"
|
|
@@ -178,7 +178,7 @@ async function sessionEventItemsFromTurns(
|
|
|
178
178
|
turnId: turn.id,
|
|
179
179
|
input: turn.input,
|
|
180
180
|
state: { status: "running" },
|
|
181
|
-
createdBy: { subjectId: "u1", subjectType: "user" },
|
|
181
|
+
createdBy: { subjectId: "u1", subjectType: "user", subjectSlug: "u1" },
|
|
182
182
|
createdAt: turn.createdAt,
|
|
183
183
|
},
|
|
184
184
|
});
|
|
@@ -636,7 +636,7 @@ describe("convertTurnMessages", () => {
|
|
|
636
636
|
input: [{ type: "user.message", content: "run tool" }],
|
|
637
637
|
state: {
|
|
638
638
|
status: "done",
|
|
639
|
-
output:
|
|
639
|
+
output: undefined,
|
|
640
640
|
requiredActions: [
|
|
641
641
|
approvalRequired({
|
|
642
642
|
id: "approval-event",
|
|
@@ -703,7 +703,7 @@ describe("convertTurnMessages", () => {
|
|
|
703
703
|
input: [{ type: "user.message", content: "run tool" }],
|
|
704
704
|
state: {
|
|
705
705
|
status: "done",
|
|
706
|
-
output:
|
|
706
|
+
output: undefined,
|
|
707
707
|
requiredActions: [
|
|
708
708
|
approvalRequired({
|
|
709
709
|
id: "approval-event",
|
|
@@ -787,7 +787,7 @@ describe("convertTurnMessages", () => {
|
|
|
787
787
|
input: [{ type: "user.message", content: "ask me" }],
|
|
788
788
|
state: {
|
|
789
789
|
status: "done",
|
|
790
|
-
output:
|
|
790
|
+
output: undefined,
|
|
791
791
|
requiredActions: [
|
|
792
792
|
responseRequired({
|
|
793
793
|
id: "resp-req-1",
|
|
@@ -859,7 +859,7 @@ describe("convertTurnMessages", () => {
|
|
|
859
859
|
input: [{ type: "user.message", content: "ask me" }],
|
|
860
860
|
state: {
|
|
861
861
|
status: "done",
|
|
862
|
-
output:
|
|
862
|
+
output: undefined,
|
|
863
863
|
requiredActions: [
|
|
864
864
|
responseRequired({
|
|
865
865
|
id: "resp-req-1",
|
|
@@ -2186,7 +2186,7 @@ describe("buildSnapshotFromSessionEvents", () => {
|
|
|
2186
2186
|
turnId: "t1",
|
|
2187
2187
|
input: [{ type: "user.message", content: "hello" }],
|
|
2188
2188
|
state: { status: "running" },
|
|
2189
|
-
createdBy: { subjectId: "u1", subjectType: "user" },
|
|
2189
|
+
createdBy: { subjectId: "u1", subjectType: "user", subjectSlug: "u1" },
|
|
2190
2190
|
createdAt,
|
|
2191
2191
|
},
|
|
2192
2192
|
},
|
|
@@ -2241,7 +2241,7 @@ describe("buildSnapshotFromSessionEvents", () => {
|
|
|
2241
2241
|
turnId: "t1",
|
|
2242
2242
|
input: [{ type: "user.message", content: "first" }],
|
|
2243
2243
|
state: { status: "running" },
|
|
2244
|
-
createdBy: { subjectId: "u1", subjectType: "user" },
|
|
2244
|
+
createdBy: { subjectId: "u1", subjectType: "user", subjectSlug: "u1" },
|
|
2245
2245
|
createdAt,
|
|
2246
2246
|
},
|
|
2247
2247
|
},
|
|
@@ -2286,7 +2286,7 @@ describe("buildSnapshotFromSessionEvents", () => {
|
|
|
2286
2286
|
turnId: "t1",
|
|
2287
2287
|
input: [{ type: "user.message", content: "first" }],
|
|
2288
2288
|
state: { status: "running" },
|
|
2289
|
-
createdBy: { subjectId: "u1", subjectType: "user" },
|
|
2289
|
+
createdBy: { subjectId: "u1", subjectType: "user", subjectSlug: "u1" },
|
|
2290
2290
|
createdAt,
|
|
2291
2291
|
},
|
|
2292
2292
|
},
|
|
@@ -2311,7 +2311,7 @@ describe("buildSnapshotFromSessionEvents", () => {
|
|
|
2311
2311
|
turnId: "t2",
|
|
2312
2312
|
input: [{ type: "user.message", content: "second" }],
|
|
2313
2313
|
state: { status: "running" },
|
|
2314
|
-
createdBy: { subjectId: "u1", subjectType: "user" },
|
|
2314
|
+
createdBy: { subjectId: "u1", subjectType: "user", subjectSlug: "u1" },
|
|
2315
2315
|
createdAt,
|
|
2316
2316
|
},
|
|
2317
2317
|
},
|
|
@@ -2380,7 +2380,7 @@ describe("buildSnapshotFromSessionEvents", () => {
|
|
|
2380
2380
|
turnId: id,
|
|
2381
2381
|
input: [{ type: "user.message", content: text }],
|
|
2382
2382
|
state: { status: "running" },
|
|
2383
|
-
createdBy: { subjectId: "u1", subjectType: "user" },
|
|
2383
|
+
createdBy: { subjectId: "u1", subjectType: "user", subjectSlug: "u1" },
|
|
2384
2384
|
createdAt,
|
|
2385
2385
|
},
|
|
2386
2386
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
|
|
3
|
-
import { mergeAgentSpec } from "./private/agentSpec.js";
|
|
3
|
+
import { mergeAgentSpec, type AgentSpec } from "./private/agentSpec.js";
|
|
4
4
|
import {
|
|
5
5
|
resolveTrueFoundryAgentConfig,
|
|
6
6
|
resolveTrueFoundryAgentRuntimeOptions,
|
|
@@ -80,14 +80,14 @@ describe("mergeAgentSpec", () => {
|
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
it("replaces mcpServers array wholesale", () => {
|
|
83
|
-
const base = {
|
|
83
|
+
const base: AgentSpec = {
|
|
84
84
|
model: { name: "openai/gpt-4o" },
|
|
85
|
-
mcpServers: [{ name: "github", enableTools: ["@all"] }],
|
|
85
|
+
mcpServers: [{ type: "truefoundry-mcp-registry", name: "github", enableTools: ["@all"] }],
|
|
86
86
|
};
|
|
87
87
|
const next = mergeAgentSpec(base, {
|
|
88
|
-
mcpServers: [{ name: "slack", enableTools: ["@all"] }],
|
|
88
|
+
mcpServers: [{ type: "truefoundry-mcp-registry", name: "slack", enableTools: ["@all"] }],
|
|
89
89
|
});
|
|
90
|
-
expect(next.mcpServers).toEqual([{ name: "slack", enableTools: ["@all"] }]);
|
|
90
|
+
expect(next.mcpServers).toEqual([{ type: "truefoundry-mcp-registry", name: "slack", enableTools: ["@all"] }]);
|
|
91
91
|
});
|
|
92
92
|
|
|
93
93
|
it("replaces skills array wholesale", () => {
|
|
@@ -102,9 +102,9 @@ describe("mergeAgentSpec", () => {
|
|
|
102
102
|
});
|
|
103
103
|
|
|
104
104
|
it("model partial update does not clear mcpServers or skills", () => {
|
|
105
|
-
const base = {
|
|
105
|
+
const base: AgentSpec = {
|
|
106
106
|
model: { name: "openai/gpt-4o", params: { maxTokens: 1024 } },
|
|
107
|
-
mcpServers: [{ name: "github", enableTools: ["@all"] }],
|
|
107
|
+
mcpServers: [{ type: "truefoundry-mcp-registry", name: "github", enableTools: ["@all"] }],
|
|
108
108
|
skills: [{ fqn: "acme/skill-a:1", preload: false }],
|
|
109
109
|
};
|
|
110
110
|
const next = mergeAgentSpec(base, {
|
|
@@ -74,7 +74,9 @@ function ensureModelMessageContentArray(message: ModelMessageEvent): void {
|
|
|
74
74
|
if (Array.isArray(message.content)) {
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
77
|
-
|
|
77
|
+
// Gateway may stream `image_url` content blocks that aren't in the SDK content union yet.
|
|
78
|
+
(message as { content?: ModelMessageContentPart[] }).content =
|
|
79
|
+
normalizeModelMessageContent(message);
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
function mergeContentBlockDeltas(
|
|
@@ -104,7 +104,7 @@ describe("createTrueFoundryDraftThreadListAdapter", () => {
|
|
|
104
104
|
const liveAgentSpec: AgentSpec = {
|
|
105
105
|
model: { name: "anthropic/claude-opus-4-8" },
|
|
106
106
|
instructions: "You are helpful.",
|
|
107
|
-
mcpServers: [{ name: "github", enableTools: ["@all"] }],
|
|
107
|
+
mcpServers: [{ type: "truefoundry-mcp-registry", name: "github", enableTools: ["@all"] }],
|
|
108
108
|
skills: [{ fqn: "acme/skill-a:1", preload: false }],
|
|
109
109
|
};
|
|
110
110
|
const createDraftSession = vi.fn().mockResolvedValue(
|
package/src/streamTurn.test.ts
CHANGED
|
@@ -13,9 +13,9 @@ const createdAt = new Date().toISOString();
|
|
|
13
13
|
|
|
14
14
|
function streamData(
|
|
15
15
|
sequenceNumber: number,
|
|
16
|
-
event: TurnStreamData["event"],
|
|
16
|
+
event: TurnStreamData["event"] | Record<string, unknown>,
|
|
17
17
|
): TurnStreamData {
|
|
18
|
-
return { sequenceNumber, event };
|
|
18
|
+
return { sequenceNumber, event: event as TurnStreamData["event"] };
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
async function collectUpdates(
|
|
@@ -150,7 +150,7 @@ describe("streamTurn", () => {
|
|
|
150
150
|
});
|
|
151
151
|
});
|
|
152
152
|
|
|
153
|
-
it("
|
|
153
|
+
it("forwards previousTurnId null when branching from root", async () => {
|
|
154
154
|
const execute = vi.fn(() => (async function* () {})());
|
|
155
155
|
const prepareTurn = vi.fn(() => ({ execute }));
|
|
156
156
|
const session = {
|
|
@@ -169,6 +169,7 @@ describe("streamTurn", () => {
|
|
|
169
169
|
|
|
170
170
|
expect(prepareTurn).toHaveBeenCalledWith({
|
|
171
171
|
input: [{ type: "user.message", content: "first" }],
|
|
172
|
+
previousTurnId: null,
|
|
172
173
|
});
|
|
173
174
|
});
|
|
174
175
|
|
|
@@ -227,6 +228,93 @@ describe("streamTurn", () => {
|
|
|
227
228
|
},
|
|
228
229
|
);
|
|
229
230
|
});
|
|
231
|
+
|
|
232
|
+
it("notifies gateway turn id when turn.done errors with no content yields", async () => {
|
|
233
|
+
const gatewayTurnId = "01ky6mqzmczwt6ssyd5r02gjjc";
|
|
234
|
+
const turn = {
|
|
235
|
+
id: undefined as string | undefined,
|
|
236
|
+
execute: vi.fn(() =>
|
|
237
|
+
(async function* () {
|
|
238
|
+
// SDK sets turn.id when turn.created is observed.
|
|
239
|
+
turn.id = gatewayTurnId;
|
|
240
|
+
yield streamData(1, {
|
|
241
|
+
type: "turn.created",
|
|
242
|
+
createdAt,
|
|
243
|
+
input: [{ type: "user.message", content: "hello" }],
|
|
244
|
+
});
|
|
245
|
+
yield streamData(2, {
|
|
246
|
+
type: "turn.done",
|
|
247
|
+
createdAt,
|
|
248
|
+
state: {
|
|
249
|
+
status: "error",
|
|
250
|
+
message:
|
|
251
|
+
"Publisher Model is not servable in region us-central1.",
|
|
252
|
+
completedAt: createdAt,
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
})(),
|
|
256
|
+
),
|
|
257
|
+
};
|
|
258
|
+
const prepareTurn = vi.fn(() => turn);
|
|
259
|
+
const session = {
|
|
260
|
+
prepareTurn,
|
|
261
|
+
cancel: vi.fn().mockResolvedValue(undefined),
|
|
262
|
+
} as unknown as AgentSession;
|
|
263
|
+
const onTurnIdAvailable = vi.fn();
|
|
264
|
+
|
|
265
|
+
await expect(
|
|
266
|
+
collectUpdates(
|
|
267
|
+
streamTurnContent(
|
|
268
|
+
session,
|
|
269
|
+
new PeerThreadFoldState(),
|
|
270
|
+
{ userMessage: "hello" },
|
|
271
|
+
new AbortController().signal,
|
|
272
|
+
undefined,
|
|
273
|
+
onTurnIdAvailable,
|
|
274
|
+
),
|
|
275
|
+
),
|
|
276
|
+
).rejects.toThrow("Publisher Model is not servable in region us-central1.");
|
|
277
|
+
|
|
278
|
+
expect(onTurnIdAvailable).toHaveBeenCalledTimes(1);
|
|
279
|
+
expect(onTurnIdAvailable).toHaveBeenCalledWith(gatewayTurnId);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it("does not notify when an error stream never assigns turn.id", async () => {
|
|
283
|
+
const execute = vi.fn(() =>
|
|
284
|
+
(async function* () {
|
|
285
|
+
yield streamData(1, {
|
|
286
|
+
type: "turn.done",
|
|
287
|
+
createdAt,
|
|
288
|
+
state: {
|
|
289
|
+
status: "error",
|
|
290
|
+
completedAt: createdAt,
|
|
291
|
+
message: "boom",
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
})(),
|
|
295
|
+
);
|
|
296
|
+
const prepareTurn = vi.fn(() => ({ id: undefined, execute }));
|
|
297
|
+
const session = {
|
|
298
|
+
prepareTurn,
|
|
299
|
+
cancel: vi.fn().mockResolvedValue(undefined),
|
|
300
|
+
} as unknown as AgentSession;
|
|
301
|
+
const onTurnIdAvailable = vi.fn();
|
|
302
|
+
|
|
303
|
+
await expect(
|
|
304
|
+
collectUpdates(
|
|
305
|
+
streamTurnContent(
|
|
306
|
+
session,
|
|
307
|
+
new PeerThreadFoldState(),
|
|
308
|
+
{ userMessage: "hello" },
|
|
309
|
+
new AbortController().signal,
|
|
310
|
+
undefined,
|
|
311
|
+
onTurnIdAvailable,
|
|
312
|
+
),
|
|
313
|
+
),
|
|
314
|
+
).rejects.toThrow("boom");
|
|
315
|
+
|
|
316
|
+
expect(onTurnIdAvailable).not.toHaveBeenCalled();
|
|
317
|
+
});
|
|
230
318
|
});
|
|
231
319
|
|
|
232
320
|
describe("resumeTurnStream", () => {
|
package/src/streamTurn.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type {
|
|
2
|
+
AgentSession,
|
|
3
|
+
Turn,
|
|
4
|
+
TurnInputItem,
|
|
5
5
|
} from "truefoundry-gateway-sdk/agents";
|
|
6
|
+
import type { TruefoundryGatewayApi } from "truefoundry-gateway-sdk";
|
|
6
7
|
|
|
7
8
|
import {
|
|
8
9
|
streamTurnEvents,
|
|
@@ -18,7 +19,7 @@ export type StreamTurnOptions = {
|
|
|
18
19
|
inputs?: RequiredActionInput[];
|
|
19
20
|
/**
|
|
20
21
|
* Branch anchor for `prepareTurn`. Omit for `"auto"`. Pass `null` for a fresh
|
|
21
|
-
* root turn
|
|
22
|
+
* root turn — sent as `previous_turn_id: null` on the wire.
|
|
22
23
|
*/
|
|
23
24
|
previousTurnId?: string | null;
|
|
24
25
|
/** Extra headers for the createTurn request (`execute` request options). */
|
|
@@ -61,13 +62,18 @@ export async function* streamTurnContent(
|
|
|
61
62
|
*/
|
|
62
63
|
onTurnIdAvailable?: (turnId: string) => void,
|
|
63
64
|
): AsyncGenerator<TurnStreamUpdate> {
|
|
64
|
-
|
|
65
|
+
// When previousTurnId is explicitly null, pass it through to prepareTurn so the
|
|
66
|
+
// SDK serializer emits `previous_turn_id: null` on the wire (first turn in session).
|
|
67
|
+
// The SDK type doesn't admit null, but the Fern serializer handles it correctly.
|
|
68
|
+
const previousTurnId: TruefoundryGatewayApi.PreviousTurnIdInput | null | undefined =
|
|
65
69
|
options.previousTurnId === null
|
|
66
|
-
?
|
|
70
|
+
? null
|
|
67
71
|
: (options.previousTurnId ?? "auto");
|
|
68
72
|
const turn = session.prepareTurn({
|
|
69
73
|
input: buildTurnInput(options),
|
|
70
|
-
...(previousTurnId
|
|
74
|
+
...(previousTurnId !== undefined
|
|
75
|
+
? { previousTurnId: previousTurnId as TruefoundryGatewayApi.PreviousTurnIdInput }
|
|
76
|
+
: {}),
|
|
71
77
|
});
|
|
72
78
|
|
|
73
79
|
const onAbort = bindAbort(session, abortSignal);
|
|
@@ -75,8 +81,15 @@ export async function* streamTurnContent(
|
|
|
75
81
|
return;
|
|
76
82
|
}
|
|
77
83
|
|
|
84
|
+
let turnIdNotified = false;
|
|
85
|
+
const notifyTurnIdIfAvailable = () => {
|
|
86
|
+
if (!turnIdNotified && turn.id != null) {
|
|
87
|
+
onTurnIdAvailable?.(turn.id);
|
|
88
|
+
turnIdNotified = true;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
78
92
|
try {
|
|
79
|
-
let turnIdNotified = false;
|
|
80
93
|
for await (const update of streamTurnEvents(
|
|
81
94
|
turn.execute(
|
|
82
95
|
{ stream: true },
|
|
@@ -91,17 +104,17 @@ export async function* streamTurnContent(
|
|
|
91
104
|
// After the first `turn.created` event, `turn.id` is set.
|
|
92
105
|
// Notify BEFORE yielding so the caller can update its tracking
|
|
93
106
|
// before the snapshot is written with the stream update.
|
|
94
|
-
|
|
95
|
-
onTurnIdAvailable?.(turn.id);
|
|
96
|
-
turnIdNotified = true;
|
|
97
|
-
}
|
|
107
|
+
notifyTurnIdIfAvailable();
|
|
98
108
|
yield update;
|
|
99
109
|
}
|
|
100
110
|
// Handle streams that complete without yielding any content.
|
|
101
|
-
|
|
102
|
-
onTurnIdAvailable?.(turn.id);
|
|
103
|
-
}
|
|
111
|
+
notifyTurnIdIfAvailable();
|
|
104
112
|
} catch (error) {
|
|
113
|
+
// Error streams often throw on `turn.done` (status=error) without ever
|
|
114
|
+
// yielding content (e.g. model not servable). `turn.id` is still set
|
|
115
|
+
// after `turn.created` — notify so edit/retry can resolve the turn.
|
|
116
|
+
// Same for AbortError after create: keep local ids aligned with gateway.
|
|
117
|
+
notifyTurnIdIfAvailable();
|
|
105
118
|
if (error instanceof Error && error.name === "AbortError") {
|
|
106
119
|
return;
|
|
107
120
|
}
|
|
@@ -596,6 +596,13 @@ export function useTrueFoundryAgentMessages({
|
|
|
596
596
|
isContinuation && continuationTurnId != null
|
|
597
597
|
? continuationTurnId
|
|
598
598
|
: generateId();
|
|
599
|
+
// First turns must send previousTurnId: null.
|
|
600
|
+
const isFirstTurnInSession =
|
|
601
|
+
"userMessage" in options &&
|
|
602
|
+
options.previousTurnId === undefined &&
|
|
603
|
+
snapshotRef.current.turns.length === 0 &&
|
|
604
|
+
snapshotRef.current.pendingUser == null &&
|
|
605
|
+
snapshotRef.current.activeStream == null;
|
|
599
606
|
|
|
600
607
|
// Mutable ref so runStream always reads the latest ID. For new
|
|
601
608
|
// user-message turns the local `generateId()` value is replaced
|
|
@@ -689,7 +696,9 @@ export function useTrueFoundryAgentMessages({
|
|
|
689
696
|
userMessage: options.userMessage,
|
|
690
697
|
...(options.previousTurnId !== undefined
|
|
691
698
|
? { previousTurnId: options.previousTurnId }
|
|
692
|
-
:
|
|
699
|
+
: isFirstTurnInSession
|
|
700
|
+
? { previousTurnId: null }
|
|
701
|
+
: {}),
|
|
693
702
|
...streamHeaders,
|
|
694
703
|
},
|
|
695
704
|
signal,
|
|
@@ -30,7 +30,6 @@ import {
|
|
|
30
30
|
createDraftSessionBridge,
|
|
31
31
|
DRAFT_SESSION_LAST_UPDATED_AT_HEADER,
|
|
32
32
|
} from "./private/draftSessionBridge.js";
|
|
33
|
-
import { getGatewayFromPrivateClient } from "./private/getGatewayFromPrivateClient.js";
|
|
34
33
|
import { MCP_AUTH_RESUME_RUN_CUSTOM_KEY } from "./mcpAuth.js";
|
|
35
34
|
import { createTrueFoundryDraftThreadListAdapter } from "./private/truefoundryDraftThreadListAdapter.js";
|
|
36
35
|
import { trueFoundryExtras } from "./truefoundryExtras.js";
|
|
@@ -164,9 +163,7 @@ function useTrueFoundryAgentRuntimeImpl(
|
|
|
164
163
|
onError?.(error);
|
|
165
164
|
throw error;
|
|
166
165
|
}
|
|
167
|
-
|
|
168
|
-
const gateway = getGatewayFromPrivateClient(privateClient);
|
|
169
|
-
const response = await gateway.agents.downloadSandboxFile(sandboxId, { path });
|
|
166
|
+
const response = await privateClient.downloadSandboxFile(sandboxId, { path });
|
|
170
167
|
return await response.blob();
|
|
171
168
|
},
|
|
172
169
|
[privateClient, sandboxId, onError],
|