@truefoundry/trueforge-ui 0.0.0 → 0.1.0-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.
Files changed (55) hide show
  1. package/CHANGELOG.md +340 -0
  2. package/LICENSE +21 -0
  3. package/NOTICE +17 -0
  4. package/README.md +640 -3
  5. package/dist/ConnectorSettings-CLBEWGQJ.js +898 -0
  6. package/dist/ConnectorSettings-CLBEWGQJ.js.map +1 -0
  7. package/dist/DockLayout-WRF7EQLD.js +35 -0
  8. package/dist/DockLayout-WRF7EQLD.js.map +1 -0
  9. package/dist/DrawerLayout-X2UXYTOS.js +156 -0
  10. package/dist/DrawerLayout-X2UXYTOS.js.map +1 -0
  11. package/dist/ModelSettings-IJ55QJQO.js +1082 -0
  12. package/dist/ModelSettings-IJ55QJQO.js.map +1 -0
  13. package/dist/OpenUiFenceBlock-SLLZSTMJ.js +9 -0
  14. package/dist/OpenUiFenceBlock-SLLZSTMJ.js.map +1 -0
  15. package/dist/SandboxSettings-S5XGZWOL.js +505 -0
  16. package/dist/SandboxSettings-S5XGZWOL.js.map +1 -0
  17. package/dist/SettingsBuilder-64Y33NP3.js +128 -0
  18. package/dist/SettingsBuilder-64Y33NP3.js.map +1 -0
  19. package/dist/SidebarLayout-M7HEOZVK.js +236 -0
  20. package/dist/SidebarLayout-M7HEOZVK.js.map +1 -0
  21. package/dist/SkillSettings-MXK4ZEI7.js +389 -0
  22. package/dist/SkillSettings-MXK4ZEI7.js.map +1 -0
  23. package/dist/WidgetLayout-7MDOKLHU.js +101 -0
  24. package/dist/WidgetLayout-7MDOKLHU.js.map +1 -0
  25. package/dist/assistant-ui.d.ts +1 -0
  26. package/dist/assistant-ui.js +9 -0
  27. package/dist/assistant-ui.js.map +1 -0
  28. package/dist/chunk-42GF723P.js +24 -0
  29. package/dist/chunk-42GF723P.js.map +1 -0
  30. package/dist/chunk-CFLVPV5M.js +29 -0
  31. package/dist/chunk-CFLVPV5M.js.map +1 -0
  32. package/dist/chunk-M6MHLVSO.js +8 -0
  33. package/dist/chunk-M6MHLVSO.js.map +1 -0
  34. package/dist/chunk-NBMP2XNL.js +89 -0
  35. package/dist/chunk-NBMP2XNL.js.map +1 -0
  36. package/dist/chunk-UBOFEI77.js +567 -0
  37. package/dist/chunk-UBOFEI77.js.map +1 -0
  38. package/dist/chunk-UHGSHDBM.js +633 -0
  39. package/dist/chunk-UHGSHDBM.js.map +1 -0
  40. package/dist/chunk-UXZOL5GO.js +2088 -0
  41. package/dist/chunk-UXZOL5GO.js.map +1 -0
  42. package/dist/chunk-WFC3W4C3.js +73 -0
  43. package/dist/chunk-WFC3W4C3.js.map +1 -0
  44. package/dist/chunk-XSHXH6EI.js +6800 -0
  45. package/dist/chunk-XSHXH6EI.js.map +1 -0
  46. package/dist/createTrueFoundryServer-B72bU-J7.d.ts +28 -0
  47. package/dist/index.d.ts +1569 -0
  48. package/dist/index.js +781 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +479 -0
  51. package/dist/plugins/trueforge-agent-server-adapter/index.js +830 -0
  52. package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -0
  53. package/dist/styles.css +2 -0
  54. package/package.json +129 -6
  55. package/index.js +0 -1
@@ -0,0 +1,830 @@
1
+ import {
2
+ createTrueFoundryServer
3
+ } from "../../chunk-CFLVPV5M.js";
4
+
5
+ // src/plugins/trueforge-agent-server-adapter/catalogs/connectorCatalog.ts
6
+ var DEFAULT_API_KEY_HEADER = "Authorization";
7
+ function toUiAuthPublic(auth) {
8
+ if (auth === void 0) {
9
+ return { type: "none" };
10
+ }
11
+ if (auth.type === "dcr") {
12
+ return { type: "dcr" };
13
+ }
14
+ const headerName = Object.keys(auth.headers)[0];
15
+ return {
16
+ type: "header",
17
+ ...headerName === void 0 ? {} : { headerName }
18
+ };
19
+ }
20
+ function toHarnessAuth(auth) {
21
+ if (auth.type === "none") {
22
+ return void 0;
23
+ }
24
+ if (auth.type === "dcr") {
25
+ return { type: "dcr" };
26
+ }
27
+ const apiKey = auth.apiKey?.trim();
28
+ if (apiKey === void 0 || apiKey === "") {
29
+ throw new Error("API key is required for header-authenticated MCP servers");
30
+ }
31
+ const trimmedHeader = auth.headerName?.trim();
32
+ const headerName = trimmedHeader !== void 0 && trimmedHeader !== "" ? trimmedHeader : DEFAULT_API_KEY_HEADER;
33
+ return { type: "header", headers: { [headerName]: apiKey } };
34
+ }
35
+ function toUiCatalogEntry(server) {
36
+ return {
37
+ id: server.name,
38
+ name: server.name,
39
+ url: server.url,
40
+ ...server.logo === void 0 ? {} : { logo: server.logo },
41
+ auth: toUiAuthPublic(server.auth)
42
+ };
43
+ }
44
+ function toUiTool(tool) {
45
+ const name = typeof tool.name === "string" && tool.name !== "" ? tool.name : "tool";
46
+ const description = typeof tool.description === "string" ? tool.description : "";
47
+ return { id: name, name, description };
48
+ }
49
+ function toUiConnector(server) {
50
+ const auth = toUiAuthPublic(server.auth);
51
+ return {
52
+ id: server.name,
53
+ name: server.name,
54
+ description: server.url,
55
+ url: server.url,
56
+ auth,
57
+ requiresAuth: server.authStatus.status === "auth_required",
58
+ authenticated: server.authStatus.status !== "auth_required"
59
+ };
60
+ }
61
+ function toUiConnectorFromReadEntry(server) {
62
+ const auth = server.auth?.type ? { type: server.auth.type } : { type: "none" };
63
+ return {
64
+ id: server.name,
65
+ name: server.name,
66
+ description: server.url,
67
+ url: server.url,
68
+ auth,
69
+ requiresAuth: server.authStatus.status === "auth_required",
70
+ authenticated: server.authStatus.status !== "auth_required"
71
+ };
72
+ }
73
+ function toHarnessManifest(req) {
74
+ const auth = toHarnessAuth(req.auth);
75
+ return {
76
+ name: req.name,
77
+ url: req.url,
78
+ ...auth === void 0 ? {} : { auth }
79
+ };
80
+ }
81
+ function createConnectorCatalog(client) {
82
+ async function getConfigured(name) {
83
+ const listed = await client.settings.mcpServers.list();
84
+ const existing = listed.data.find((server) => server.name === name);
85
+ if (existing === void 0) {
86
+ throw new Error(`MCP server "${name}" not found`);
87
+ }
88
+ return existing;
89
+ }
90
+ async function resolveWriteAuth(req) {
91
+ if (req.auth.type !== "header") {
92
+ return req.auth;
93
+ }
94
+ const apiKey = req.auth.apiKey?.trim();
95
+ if (apiKey !== void 0 && apiKey !== "") {
96
+ return req.auth;
97
+ }
98
+ if (req.id === void 0) {
99
+ throw new Error("API key is required for header-authenticated MCP servers");
100
+ }
101
+ const existing = await getConfigured(req.id);
102
+ if (existing.auth?.type !== "header") {
103
+ throw new Error(`MCP server "${req.id}" has no stored header credentials to reuse`);
104
+ }
105
+ const preferredHeader = req.auth.headerName?.trim();
106
+ const storedHeaderName = Object.keys(existing.auth.headers)[0];
107
+ const headerName = preferredHeader !== void 0 && preferredHeader !== "" ? preferredHeader : storedHeaderName ?? DEFAULT_API_KEY_HEADER;
108
+ const stored = existing.auth.headers[headerName] ?? Object.values(existing.auth.headers)[0];
109
+ if (stored === void 0) {
110
+ throw new Error(`MCP server "${req.id}" has no stored header credentials to reuse`);
111
+ }
112
+ return { type: "header", apiKey: stored, headerName };
113
+ }
114
+ return {
115
+ getConnectorCatalog: async () => {
116
+ const body = await client.catalog.mcpServers.list();
117
+ return body.data.map(toUiCatalogEntry);
118
+ },
119
+ getConnector: async (req) => {
120
+ const body = await client.settings.mcpServers.get(req.id);
121
+ return toUiConnector(body.data);
122
+ },
123
+ listConnectors: async (req) => {
124
+ const body = await client.settings.mcpServers.list();
125
+ const connectors = body.data.map(toUiConnector);
126
+ const query = req?.query?.trim().toLowerCase();
127
+ if (query === void 0 || query === "") {
128
+ return connectors;
129
+ }
130
+ return connectors.filter(
131
+ (connector) => connector.name.toLowerCase().includes(query) || connector.description.toLowerCase().includes(query) || connector.url.toLowerCase().includes(query)
132
+ );
133
+ },
134
+ getToolsByConnectorId: async ({ id }) => {
135
+ const body = await client.settings.mcpServers.listTools(id);
136
+ return body.data.map(toUiTool);
137
+ },
138
+ createConnector: async (req) => {
139
+ const auth = await resolveWriteAuth({ auth: req.auth });
140
+ const body = await client.settings.mcpServers.create(toHarnessManifest({ name: req.name, url: req.url, auth }));
141
+ return toUiConnector(body.data);
142
+ },
143
+ updateConnector: async (req) => {
144
+ const auth = await resolveWriteAuth({ id: req.id, auth: req.auth });
145
+ const body = await client.settings.mcpServers.upsert(toHarnessManifest({ name: req.id, url: req.url, auth }));
146
+ return toUiConnector(body.data);
147
+ },
148
+ authenticateConnector: async (req) => {
149
+ const result = await client.mcpServers.authorize(
150
+ req.id,
151
+ req.redirectURL === void 0 ? {} : { redirectUrl: req.redirectURL }
152
+ );
153
+ return { status: result.status, authorization_endpoint: result.authorizationUrl };
154
+ },
155
+ disconnectConnector: async (req) => {
156
+ const existing = await getConfigured(req.id);
157
+ if (existing.auth?.type !== "dcr") {
158
+ throw new Error(`Disconnect is only supported for OAuth MCP servers`);
159
+ }
160
+ const body = await client.mcpServers.deleteAuthorize(req.id);
161
+ return toUiConnector(body.data);
162
+ }
163
+ };
164
+ }
165
+
166
+ // src/plugins/trueforge-agent-server-adapter/client.ts
167
+ import { TrueForge } from "@truefoundry/trueforge-sdk";
168
+ var DEFAULT_BASE_URL = "/";
169
+ function createTrueForgeClient(options = {}) {
170
+ return new TrueForge({
171
+ baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
172
+ ...options.token === void 0 ? {} : { token: options.token },
173
+ ...options.fetch === void 0 ? {} : { fetch: options.fetch }
174
+ });
175
+ }
176
+
177
+ // src/plugins/trueforge-agent-server-adapter/chatServer.ts
178
+ function toUiMcpServer(server) {
179
+ return server;
180
+ }
181
+ function toUiSkill(skill) {
182
+ return { name: skill.name };
183
+ }
184
+ function toHarnessAgentSpec(spec) {
185
+ const { skills, mcpServers, ...rest } = spec;
186
+ return {
187
+ ...rest,
188
+ ...mcpServers === void 0 ? {} : {
189
+ mcpServers: mcpServers.map((server) => {
190
+ if ("id" in server) {
191
+ const { id, ...mount } = server;
192
+ void id;
193
+ return mount;
194
+ }
195
+ return server;
196
+ })
197
+ },
198
+ ...skills === void 0 ? {} : { skills: skills.map(({ name }) => ({ name })) }
199
+ };
200
+ }
201
+ function toUiAgentSpec(spec) {
202
+ const { mcpServers, skills, ...rest } = spec;
203
+ return {
204
+ ...rest,
205
+ ...mcpServers ? { mcpServers: mcpServers.map(toUiMcpServer) } : {},
206
+ ...skills ? { skills: skills.map(toUiSkill) } : {}
207
+ };
208
+ }
209
+ function toUiSession(session) {
210
+ return {
211
+ id: session.id,
212
+ isMutable: session.agent.type === "inline",
213
+ createdAt: session.createdAt,
214
+ updatedAt: session.updatedAt,
215
+ ...session.title === null ? {} : { title: session.title },
216
+ // `name` is a create-time snapshot, so references whose agent predates it stay
217
+ // unlabelled; `isMutable` alone keeps them out of the composer.
218
+ ...session.agent.type === "reference" && session.agent.name !== null ? { agentName: session.agent.name } : {},
219
+ ...session.agent.type === "inline" ? { agentSpec: toUiAgentSpec(session.agent.spec) } : {}
220
+ };
221
+ }
222
+ function toUiContent(content) {
223
+ return typeof content === "string" ? content : content.map((part) => ({ ...part }));
224
+ }
225
+ function toUiInput(input) {
226
+ return input.map((item) => item.type === "user.message" ? { ...item, content: toUiContent(item.content) } : item);
227
+ }
228
+ function toUiTurn(turn) {
229
+ const { previousTurnId, input, ...rest } = turn;
230
+ return {
231
+ ...rest,
232
+ ...previousTurnId === null ? {} : { previousTurnId },
233
+ ...input === void 0 ? {} : { input: toUiInput(input) }
234
+ };
235
+ }
236
+ function toUiEventItem(item) {
237
+ return { turnId: item.turnId, event: { ...item.event } };
238
+ }
239
+ function toListResult(page, map) {
240
+ const data = page.data.map(map);
241
+ const token = page.response.pagination.nextPageToken;
242
+ return {
243
+ data,
244
+ ...token === void 0 ? {} : { nextPageToken: token }
245
+ };
246
+ }
247
+ function sequenceNumber(id, fallback) {
248
+ if (id === void 0) return fallback;
249
+ const parsed = Number(id);
250
+ return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : fallback;
251
+ }
252
+ function toHarnessContent(content) {
253
+ if (typeof content === "string") return content;
254
+ return content.map((part) => {
255
+ if (part.type === "text") return part;
256
+ const { name, data } = part;
257
+ if (typeof name !== "string" || typeof data !== "string") {
258
+ throw new Error("File attachment must carry a string `name` and a data-URI `data`");
259
+ }
260
+ return { type: "file", name, data };
261
+ });
262
+ }
263
+ function toHarnessInput(input) {
264
+ return input.map(
265
+ (item) => item.type === "user.message" ? { ...item, content: toHarnessContent(item.content) } : item
266
+ );
267
+ }
268
+ function createHarnessChatServer(options = {}) {
269
+ const client = options.client ?? createTrueForgeClient(options);
270
+ return {
271
+ // The sandbox is resolved server-side from the turn, so `sandboxId` is accepted for parity
272
+ // with hosts that address sandboxes directly and deliberately not forwarded.
273
+ async downloadSandboxFile({ sessionId, turnId, path }) {
274
+ const response = await client.sessions.downloadSandboxFile(sessionId, turnId, { path });
275
+ return response.blob();
276
+ },
277
+ async createSession(request) {
278
+ if (request.agentName !== void 0 && request.agentName.length > 0) {
279
+ const created = await client.sessions.create({
280
+ agent: { name: request.agentName }
281
+ });
282
+ return toUiSession(created.data);
283
+ }
284
+ if (request.agentSpec !== void 0) {
285
+ const created = await client.sessions.create({
286
+ agent: { spec: toHarnessAgentSpec(request.agentSpec) }
287
+ });
288
+ return toUiSession(created.data);
289
+ }
290
+ throw new Error("createSession requires agentName or agentSpec");
291
+ },
292
+ async listSessions(request = {}) {
293
+ const page = await client.sessions.list({
294
+ ...request.limit === void 0 ? {} : { limit: request.limit },
295
+ ...request.order === void 0 ? {} : { order: request.order },
296
+ ...request.pageToken === void 0 ? {} : { pageToken: request.pageToken },
297
+ ...request.agentId === void 0 || request.agentId.length === 0 ? {} : { agentId: request.agentId }
298
+ });
299
+ return toListResult(page, toUiSession);
300
+ },
301
+ async getSession({ sessionId }) {
302
+ const response = await client.sessions.get(sessionId);
303
+ return toUiSession(response.data);
304
+ },
305
+ async updateSession({ sessionId, agentSpec }) {
306
+ const response = await client.sessions.update(sessionId, {
307
+ ...agentSpec === void 0 ? {} : { agent: { spec: toHarnessAgentSpec(agentSpec) } }
308
+ });
309
+ return toUiSession(response.data);
310
+ },
311
+ async *createTurn({
312
+ sessionId,
313
+ input,
314
+ previousTurnId
315
+ }) {
316
+ const stream = await client.sessions.createTurnStream(sessionId, {
317
+ ...input === void 0 ? {} : { input: toHarnessInput(input) },
318
+ ...previousTurnId === void 0 ? {} : { previousTurnId }
319
+ });
320
+ let fallbackSequence = 0;
321
+ for await (const item of stream.withMetadata()) {
322
+ yield {
323
+ sequenceNumber: sequenceNumber(item.id, fallbackSequence),
324
+ event: { ...item.data }
325
+ };
326
+ fallbackSequence += 1;
327
+ }
328
+ },
329
+ /** Resume a live turn; omitted/0 `afterSequenceNumber` replays from the start. */
330
+ async *subscribeToTurn({
331
+ sessionId,
332
+ turnId,
333
+ afterSequenceNumber
334
+ }) {
335
+ const stream = await client.sessions.subscribeToTurn(sessionId, turnId, {
336
+ ...afterSequenceNumber === void 0 ? {} : { afterSequenceNumber }
337
+ });
338
+ let fallbackSequence = 0;
339
+ for await (const item of stream.withMetadata()) {
340
+ yield {
341
+ sequenceNumber: sequenceNumber(item.id, fallbackSequence),
342
+ event: { ...item.data }
343
+ };
344
+ fallbackSequence += 1;
345
+ }
346
+ },
347
+ async cancelSession({ sessionId }) {
348
+ await client.sessions.cancel(sessionId);
349
+ },
350
+ async listTurns({ sessionId, limit, pageToken }) {
351
+ const page = await client.sessions.listTurns(sessionId, {
352
+ ...limit === void 0 ? {} : { limit },
353
+ ...pageToken === void 0 ? {} : { pageToken }
354
+ });
355
+ return toListResult(page, toUiTurn);
356
+ },
357
+ async getTurn({ sessionId, turnId }) {
358
+ const response = await client.sessions.getTurn(sessionId, turnId);
359
+ return toUiTurn(response.data);
360
+ },
361
+ async listEvents({ sessionId, pageToken, lastTurnId, limit }) {
362
+ const page = await client.sessions.listEvents(sessionId, {
363
+ ...pageToken === void 0 ? {} : { pageToken },
364
+ ...lastTurnId === void 0 ? {} : { lastTurnId },
365
+ ...limit === void 0 ? {} : { limit }
366
+ });
367
+ return toListResult(page, toUiEventItem);
368
+ }
369
+ };
370
+ }
371
+
372
+ // src/plugins/trueforge-agent-server-adapter/lists.ts
373
+ async function listModels(client) {
374
+ const body = await client.models.list();
375
+ return body.data;
376
+ }
377
+ async function listConfiguredMcpServers(client) {
378
+ const body = await client.mcpServers.list();
379
+ return body.data;
380
+ }
381
+ async function listSkills(client) {
382
+ const body = await client.skills.list();
383
+ return body.data;
384
+ }
385
+ async function getCapabilities(client) {
386
+ const body = await client.server.getCapabilities();
387
+ return body.data;
388
+ }
389
+
390
+ // src/plugins/trueforge-agent-server-adapter/builderServer.ts
391
+ function modelProviderLogosByName(catalog) {
392
+ const logos = /* @__PURE__ */ new Map();
393
+ for (const entry of catalog) {
394
+ if (entry.type === "custom" || entry.logo === void 0) {
395
+ continue;
396
+ }
397
+ logos.set(entry.type, entry.logo);
398
+ }
399
+ return logos;
400
+ }
401
+ function toModelSelection({ model, logo }) {
402
+ const efforts = model.properties.reasoningEfforts;
403
+ return {
404
+ id: model.modelId,
405
+ name: model.name,
406
+ provider: {
407
+ name: model.provider.name,
408
+ ...logo === void 0 ? {} : { logo }
409
+ },
410
+ properties: {
411
+ ...efforts !== void 0 && efforts.length > 0 ? { reasoningEfforts: [...efforts] } : {}
412
+ }
413
+ };
414
+ }
415
+ function toLibraryEntry(agent) {
416
+ return {
417
+ name: agent.name,
418
+ agentId: agent.id,
419
+ agentSpec: toUiAgentSpec(agent.manifest)
420
+ };
421
+ }
422
+ function createHarnessBuilderServer(options = {}) {
423
+ const client = options.client ?? createTrueForgeClient(options);
424
+ return {
425
+ getCapabilities: () => client.server.getCapabilities(),
426
+ getModels: async () => {
427
+ const [modelsBody, catalogEntries] = await Promise.all([
428
+ client.models.list(),
429
+ client.catalog.modelProviders.list().then(
430
+ (body) => body.data,
431
+ () => []
432
+ )
433
+ ]);
434
+ const logosByName = modelProviderLogosByName(catalogEntries);
435
+ return modelsBody.data.map((model) => {
436
+ const logo = logosByName.get(model.provider.name);
437
+ return toModelSelection(logo === void 0 ? { model } : { model, logo });
438
+ });
439
+ },
440
+ // Skills require a configured sandbox provider; keep the picker empty when skill capability is off.
441
+ getSkills: async () => {
442
+ const skills = await listSkills(client);
443
+ return skills.map((skill) => ({ id: skill.name, name: skill.name, description: skill.description }));
444
+ },
445
+ getMcp: async () => (await listConfiguredMcpServers(client)).map(toUiConnectorFromReadEntry),
446
+ async searchAgents(req) {
447
+ const { data } = await client.agents.list();
448
+ const query = req?.query?.trim().toLowerCase();
449
+ const filtered = query === void 0 || query === "" ? data : data.filter((agent) => agent.name.toLowerCase().includes(query));
450
+ const offset = req?.offset ?? 0;
451
+ const limit = req?.limit ?? 50;
452
+ return filtered.slice(offset, offset + limit).map(toLibraryEntry);
453
+ },
454
+ async saveAgent({ agentName, agentSpec, intent }) {
455
+ const manifest = toHarnessAgentSpec(agentSpec);
456
+ if (intent === "update") {
457
+ const { data } = await client.agents.list();
458
+ const existing = data.find((agent) => agent.name === agentName);
459
+ if (!existing) {
460
+ return {};
461
+ }
462
+ await client.agents.update(existing.id, { manifest });
463
+ return { agentId: existing.id };
464
+ }
465
+ const created = await client.agents.create({ name: agentName, manifest });
466
+ return { agentId: created.data.id };
467
+ }
468
+ };
469
+ }
470
+
471
+ // src/plugins/trueforge-agent-server-adapter/catalogs/modelProviderCatalog.ts
472
+ import { TrueForgeApi } from "@truefoundry/trueforge-sdk";
473
+ function toUiModelEntry(model) {
474
+ return {
475
+ id: model.modelId,
476
+ name: model.name,
477
+ properties: model.properties
478
+ };
479
+ }
480
+ function toHarnessModelEntry(model) {
481
+ return {
482
+ modelId: model.id,
483
+ name: model.name,
484
+ properties: model.properties ?? {}
485
+ };
486
+ }
487
+ function toUiModelProvider(provider) {
488
+ const name = provider.type === "custom" ? provider.name : provider.type;
489
+ return {
490
+ id: name,
491
+ type: provider.type,
492
+ name,
493
+ ...provider.baseUrl === void 0 ? {} : { baseUrl: provider.baseUrl },
494
+ models: provider.models.map(toUiModelEntry)
495
+ };
496
+ }
497
+ function toUiCatalogModelProviderEntry(provider) {
498
+ if (provider.type === "custom") {
499
+ return {
500
+ type: provider.type,
501
+ name: provider.type,
502
+ supportedReasoningEfforts: provider.supportedReasoningEfforts,
503
+ models: []
504
+ };
505
+ }
506
+ return {
507
+ type: provider.type,
508
+ name: provider.type,
509
+ ...provider.logo === void 0 ? {} : { logo: provider.logo },
510
+ models: provider.models.map(toUiModelEntry)
511
+ };
512
+ }
513
+ var PROVIDER_TYPES = [...Object.values(TrueForgeApi.CatalogWellKnownModelProviderType), "custom"];
514
+ function isProviderType(type) {
515
+ return PROVIDER_TYPES.includes(type);
516
+ }
517
+ function toHarnessModelProvider(req) {
518
+ const models = req.models.map(toHarnessModelEntry);
519
+ if (!isProviderType(req.type)) {
520
+ throw new Error(`Unsupported model provider type: ${req.type}`);
521
+ }
522
+ const baseUrl = req.baseUrl?.trim() === "" ? void 0 : req.baseUrl;
523
+ if (req.type === "custom") {
524
+ if (baseUrl === void 0) {
525
+ throw new Error(`Model providers of type "${req.type}" require a base URL`);
526
+ }
527
+ return {
528
+ type: req.type,
529
+ name: req.name,
530
+ models,
531
+ baseUrl,
532
+ ...req.apiKey === "" ? {} : { auth: { apiKey: req.apiKey } }
533
+ };
534
+ }
535
+ const auth = { apiKey: req.apiKey };
536
+ if (baseUrl !== void 0) {
537
+ return { type: req.type, auth, models, baseUrl };
538
+ }
539
+ return { type: req.type, auth, models };
540
+ }
541
+ function createModelProviderCatalog(client) {
542
+ async function resolveApiKey(req) {
543
+ const trimmed = req.apiKey.trim();
544
+ if (trimmed !== "") {
545
+ return trimmed;
546
+ }
547
+ if (req.id === void 0) {
548
+ if (req.type === "custom") {
549
+ return "";
550
+ }
551
+ throw new Error("API key is required");
552
+ }
553
+ const listed = await client.settings.modelProviders.list();
554
+ const existing = listed.data.find((provider) => toUiModelProvider(provider).id === req.id);
555
+ if (existing === void 0) {
556
+ throw new Error(`Model provider "${req.id}" not found`);
557
+ }
558
+ return existing.auth?.apiKey ?? "";
559
+ }
560
+ return {
561
+ getModelProviderCatalog: async () => {
562
+ const body = await client.catalog.modelProviders.list();
563
+ return body.data.map(toUiCatalogModelProviderEntry);
564
+ },
565
+ listModelProviders: async () => {
566
+ const body = await client.settings.modelProviders.list();
567
+ return body.data.map(toUiModelProvider);
568
+ },
569
+ createModelProvider: async (req) => {
570
+ const apiKey = await resolveApiKey({ type: req.type, apiKey: req.apiKey });
571
+ const body = await client.settings.modelProviders.create(
572
+ toHarnessModelProvider({
573
+ type: req.type,
574
+ name: req.name,
575
+ apiKey,
576
+ ...req.baseUrl === void 0 ? {} : { baseUrl: req.baseUrl },
577
+ models: req.models
578
+ })
579
+ );
580
+ return toUiModelProvider(body.data);
581
+ },
582
+ updateModelProvider: async (req) => {
583
+ const apiKey = await resolveApiKey({ id: req.id, type: req.type, apiKey: req.apiKey });
584
+ const body = await client.settings.modelProviders.upsert(
585
+ toHarnessModelProvider({
586
+ type: req.type,
587
+ name: req.id,
588
+ apiKey,
589
+ ...req.baseUrl === void 0 ? {} : { baseUrl: req.baseUrl },
590
+ models: req.models
591
+ })
592
+ );
593
+ return toUiModelProvider(body.data);
594
+ }
595
+ };
596
+ }
597
+
598
+ // src/plugins/trueforge-agent-server-adapter/catalogs/sandboxProviderCatalog.ts
599
+ import { TrueForgeApi as TrueForgeApi2 } from "@truefoundry/trueforge-sdk";
600
+ var DAYTONA_TYPE = "daytona";
601
+ var DAYTONA_DISPLAY_NAME = "Daytona";
602
+ function displayNameForType(type) {
603
+ if (type === DAYTONA_TYPE) {
604
+ return DAYTONA_DISPLAY_NAME;
605
+ }
606
+ return type;
607
+ }
608
+ function configFromHarness(provider) {
609
+ return {
610
+ // Snapshot/image is now release-owned; the field is gone from the backend. The external
611
+ // SandboxProviderConfig still requires it, so send an empty placeholder until that type drops it.
612
+ snapshotName: "",
613
+ execTimeoutMs: provider.execTimeoutMs,
614
+ autoStopIntervalInMinutes: provider.autoStopIntervalInMinutes,
615
+ autoArchiveIntervalInMinutes: provider.autoArchiveIntervalInMinutes,
616
+ autoDeleteIntervalInMinutes: provider.autoDeleteIntervalInMinutes
617
+ };
618
+ }
619
+ function toUiCatalogEntry2(provider) {
620
+ return {
621
+ id: provider.type,
622
+ name: displayNameForType(provider.type),
623
+ type: provider.type,
624
+ ...configFromHarness(provider)
625
+ };
626
+ }
627
+ function toUiSandboxProvider(provider) {
628
+ return {
629
+ id: provider.type,
630
+ name: displayNameForType(provider.type),
631
+ catalogId: provider.type,
632
+ isConnected: true,
633
+ ...configFromHarness(provider)
634
+ };
635
+ }
636
+ function toHarnessManifest2(req) {
637
+ if (req.type !== DAYTONA_TYPE) {
638
+ throw new Error(`Unsupported sandbox provider type: ${req.type}`);
639
+ }
640
+ return {
641
+ type: DAYTONA_TYPE,
642
+ execTimeoutMs: req.execTimeoutMs,
643
+ autoStopIntervalInMinutes: req.autoStopIntervalInMinutes,
644
+ autoArchiveIntervalInMinutes: req.autoArchiveIntervalInMinutes,
645
+ autoDeleteIntervalInMinutes: req.autoDeleteIntervalInMinutes,
646
+ auth: { apiKey: req.apiKey }
647
+ };
648
+ }
649
+ function createSandboxProviderCatalog(client) {
650
+ async function resolveApiKey(apiKey) {
651
+ const trimmed = apiKey?.trim();
652
+ if (trimmed !== void 0 && trimmed !== "") {
653
+ return trimmed;
654
+ }
655
+ const existing = await client.settings.sandboxProviders.get();
656
+ return existing.data.manifest.auth.apiKey;
657
+ }
658
+ return {
659
+ getSandboxProviderCatalog: async () => {
660
+ const body = await client.catalog.sandboxProviders.list();
661
+ return body.data.map(toUiCatalogEntry2);
662
+ },
663
+ listSandboxProviders: async (req) => {
664
+ let providers;
665
+ try {
666
+ const body = await client.settings.sandboxProviders.get();
667
+ providers = [toUiSandboxProvider(body.data.manifest)];
668
+ } catch (err) {
669
+ if (err instanceof TrueForgeApi2.NotFoundError) {
670
+ providers = [];
671
+ } else {
672
+ throw err;
673
+ }
674
+ }
675
+ const query = req?.query?.trim().toLowerCase();
676
+ if (query === void 0 || query === "") {
677
+ return providers;
678
+ }
679
+ return providers.filter(
680
+ (provider) => provider.name.toLowerCase().includes(query) || provider.id.toLowerCase().includes(query)
681
+ );
682
+ },
683
+ createSandboxProvider: async (req) => {
684
+ const body = await client.settings.sandboxProviders.upsert(
685
+ toHarnessManifest2({
686
+ type: req.type,
687
+ apiKey: req.apiKey,
688
+ execTimeoutMs: req.execTimeoutMs,
689
+ autoStopIntervalInMinutes: req.autoStopIntervalInMinutes,
690
+ autoArchiveIntervalInMinutes: req.autoArchiveIntervalInMinutes,
691
+ autoDeleteIntervalInMinutes: req.autoDeleteIntervalInMinutes
692
+ })
693
+ );
694
+ return toUiSandboxProvider(body.data.manifest);
695
+ },
696
+ updateSandboxProvider: async (req) => {
697
+ const apiKey = await resolveApiKey(req.apiKey);
698
+ const body = await client.settings.sandboxProviders.upsert(
699
+ toHarnessManifest2({
700
+ type: DAYTONA_TYPE,
701
+ apiKey,
702
+ execTimeoutMs: req.execTimeoutMs,
703
+ autoStopIntervalInMinutes: req.autoStopIntervalInMinutes,
704
+ autoArchiveIntervalInMinutes: req.autoArchiveIntervalInMinutes,
705
+ autoDeleteIntervalInMinutes: req.autoDeleteIntervalInMinutes
706
+ })
707
+ );
708
+ return toUiSandboxProvider(body.data.manifest);
709
+ }
710
+ };
711
+ }
712
+
713
+ // src/plugins/trueforge-agent-server-adapter/catalogs/skillCatalog.ts
714
+ function toUiCatalogEntry3(skill) {
715
+ return {
716
+ id: skill.name,
717
+ name: skill.name,
718
+ description: skill.description,
719
+ repoURL: skill.url,
720
+ path: skill.path ?? "",
721
+ ref: skill.ref
722
+ };
723
+ }
724
+ function toHarnessManifest3(req) {
725
+ const path = req.path.trim();
726
+ return {
727
+ type: "git",
728
+ name: req.name,
729
+ url: req.repoURL,
730
+ ...path === "" ? {} : { path },
731
+ ref: req.ref,
732
+ description: req.description
733
+ };
734
+ }
735
+ function toUiSkill2(skill, catalogNames) {
736
+ const base = {
737
+ id: skill.name,
738
+ name: skill.name,
739
+ description: skill.description
740
+ };
741
+ if (catalogNames.has(skill.name)) {
742
+ return { ...base, catalogId: skill.name };
743
+ }
744
+ return base;
745
+ }
746
+ function createSkillCatalog(client) {
747
+ return {
748
+ getSkillCatalog: async () => {
749
+ const body = await client.catalog.skills.list();
750
+ return body.data.map(toUiCatalogEntry3);
751
+ },
752
+ listSkills: async (req) => {
753
+ const [listed, catalog] = await Promise.all([client.settings.skills.list(), client.catalog.skills.list()]);
754
+ const catalogNames = new Set(catalog.data.map((entry) => entry.name));
755
+ const skills = listed.data.map((skill) => toUiSkill2(skill, catalogNames));
756
+ const query = req?.query?.trim().toLowerCase();
757
+ if (query === void 0 || query === "") {
758
+ return skills;
759
+ }
760
+ return skills.filter(
761
+ (skill) => skill.name.toLowerCase().includes(query) || skill.description.toLowerCase().includes(query)
762
+ );
763
+ },
764
+ createSkill: async (req) => {
765
+ const body = await client.settings.skills.create(toHarnessManifest3(req));
766
+ const catalogId = "catalogId" in req ? req.catalogId : void 0;
767
+ if (catalogId !== void 0) {
768
+ return {
769
+ id: body.data.name,
770
+ name: body.data.name,
771
+ description: body.data.description,
772
+ catalogId
773
+ };
774
+ }
775
+ return {
776
+ id: body.data.name,
777
+ name: body.data.name,
778
+ description: body.data.description
779
+ };
780
+ }
781
+ };
782
+ }
783
+
784
+ // src/plugins/trueforge-agent-server-adapter/index.ts
785
+ function createTrueForgeAgentUIServer(options = {}) {
786
+ const { catalog: catalogOverride, ...clientOptions } = options;
787
+ const client = createTrueForgeClient(clientOptions);
788
+ const catalog = catalogOverride ?? {
789
+ modelCatalog: createModelProviderCatalog(client),
790
+ connectorCatalog: createConnectorCatalog(client),
791
+ skillCatalog: createSkillCatalog(client),
792
+ sandboxCatalog: createSandboxProviderCatalog(client)
793
+ };
794
+ return createTrueFoundryServer({
795
+ chatServer: createHarnessChatServer({ client }),
796
+ ...createHarnessBuilderServer({ client }),
797
+ catalog
798
+ });
799
+ }
800
+ export {
801
+ configFromHarness,
802
+ createConnectorCatalog,
803
+ createHarnessBuilderServer,
804
+ createHarnessChatServer,
805
+ createModelProviderCatalog,
806
+ createSandboxProviderCatalog,
807
+ createSkillCatalog,
808
+ createTrueForgeAgentUIServer,
809
+ createTrueForgeClient,
810
+ getCapabilities,
811
+ listConfiguredMcpServers,
812
+ listModels,
813
+ listSkills,
814
+ modelProviderLogosByName,
815
+ toHarnessAgentSpec,
816
+ toHarnessAuth,
817
+ toHarnessManifest as toHarnessConnectorManifest,
818
+ toHarnessModelProvider,
819
+ toHarnessManifest2 as toHarnessSandboxManifest,
820
+ toHarnessManifest3 as toHarnessSkillManifest,
821
+ toModelSelection,
822
+ toUiAgentSpec,
823
+ toUiCatalogModelProviderEntry,
824
+ toUiConnector,
825
+ toUiConnectorFromReadEntry,
826
+ toUiModelProvider,
827
+ toUiSandboxProvider,
828
+ toUiSkill2 as toUiSkill
829
+ };
830
+ //# sourceMappingURL=index.js.map