@truefoundry/trueforge-ui 0.3.0-rc.0 → 0.3.0-rc.1

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 (110) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +14 -6
  3. package/dist/AgentCodeSnippets-NZOFJE57.js +74 -0
  4. package/dist/AgentCodeSnippets-NZOFJE57.js.map +1 -0
  5. package/dist/AgentMetricChart-JPU3MFQ2.js +15 -0
  6. package/dist/AgentOverview-EEBHJC32.js +167 -0
  7. package/dist/AgentOverview-EEBHJC32.js.map +1 -0
  8. package/dist/AgentSessionEventTimeline-26Z6IB3B.js +79 -0
  9. package/dist/AgentSessionEventTimeline-26Z6IB3B.js.map +1 -0
  10. package/dist/AgentSessionEventTimelineChart-CGCU7WBK.js +504 -0
  11. package/dist/AgentSessionEventTimelineChart-CGCU7WBK.js.map +1 -0
  12. package/dist/AgentSessions-3MPDZASK.js +275 -0
  13. package/dist/AgentSessions-3MPDZASK.js.map +1 -0
  14. package/dist/{ConnectorSettings-FXQ5B7TN.js → ConnectorSettings-MXFRWWR6.js} +8 -6
  15. package/dist/{ConnectorSettings-FXQ5B7TN.js.map → ConnectorSettings-MXFRWWR6.js.map} +1 -1
  16. package/dist/{DockLayout-LBNQJZNF.js → DockLayout-LM4AFMFY.js} +11 -10
  17. package/dist/{DockLayout-LBNQJZNF.js.map → DockLayout-LM4AFMFY.js.map} +1 -1
  18. package/dist/DrawerLayout-JR3O6RRB.js +184 -0
  19. package/dist/DrawerLayout-JR3O6RRB.js.map +1 -0
  20. package/dist/{ModelSettings-4L4LOQJA.js → ModelSettings-G7IFNC2Y.js} +8 -6
  21. package/dist/{ModelSettings-4L4LOQJA.js.map → ModelSettings-G7IFNC2Y.js.map} +1 -1
  22. package/dist/OpenUiFenceBlock-2TV5TQ6P.js +9 -0
  23. package/dist/OpenUiFenceBlock-2TV5TQ6P.js.map +1 -0
  24. package/dist/{SandboxSettings-Z4ZG6ZX4.js → SandboxSettings-NXAANMAX.js} +8 -6
  25. package/dist/{SandboxSettings-Z4ZG6ZX4.js.map → SandboxSettings-NXAANMAX.js.map} +1 -1
  26. package/dist/SchedulesPage-KKLUDO6B.js +15 -0
  27. package/dist/SchedulesPage-KKLUDO6B.js.map +1 -0
  28. package/dist/{SettingsBuilder-WF7ZWKQW.js → SettingsBuilder-L34IQ56S.js} +26 -22
  29. package/dist/SettingsBuilder-L34IQ56S.js.map +1 -0
  30. package/dist/{ShellRouteSync-T4WLY57Q.js → ShellRouteSync-CEBETGEJ.js} +95 -22
  31. package/dist/ShellRouteSync-CEBETGEJ.js.map +1 -0
  32. package/dist/SidebarLayout-A2HJPPHS.js +308 -0
  33. package/dist/SidebarLayout-A2HJPPHS.js.map +1 -0
  34. package/dist/{SkillSettings-3EPPC3IT.js → SkillSettings-FGGMSUNO.js} +8 -6
  35. package/dist/{SkillSettings-3EPPC3IT.js.map → SkillSettings-FGGMSUNO.js.map} +1 -1
  36. package/dist/{TrueForgeUIWithRouter-NZ4FGPE4.js → TrueForgeUIWithRouter-MZVJWJMB.js} +14 -10
  37. package/dist/{TrueForgeUIWithRouter-NZ4FGPE4.js.map → TrueForgeUIWithRouter-MZVJWJMB.js.map} +1 -1
  38. package/dist/{WidgetLayout-3QZ357FL.js → WidgetLayout-6QM45OQQ.js} +17 -13
  39. package/dist/WidgetLayout-6QM45OQQ.js.map +1 -0
  40. package/dist/chunk-2XPPBEYF.js +74 -0
  41. package/dist/chunk-2XPPBEYF.js.map +1 -0
  42. package/dist/chunk-6O6FWUDW.js +1376 -0
  43. package/dist/chunk-6O6FWUDW.js.map +1 -0
  44. package/dist/chunk-7Z2C2K7F.js +578 -0
  45. package/dist/chunk-7Z2C2K7F.js.map +1 -0
  46. package/dist/{chunk-WREC7D54.js → chunk-CYHJDKFB.js} +115 -32
  47. package/dist/chunk-CYHJDKFB.js.map +1 -0
  48. package/dist/chunk-DJUFS2BW.js +27 -0
  49. package/dist/chunk-DJUFS2BW.js.map +1 -0
  50. package/dist/chunk-DMMZSZTN.js +252 -0
  51. package/dist/chunk-DMMZSZTN.js.map +1 -0
  52. package/dist/chunk-FJW36PD7.js +180 -0
  53. package/dist/chunk-FJW36PD7.js.map +1 -0
  54. package/dist/chunk-M62XY4NC.js +555 -0
  55. package/dist/chunk-M62XY4NC.js.map +1 -0
  56. package/dist/{chunk-B52K63AW.js → chunk-MPNSO7E6.js} +2 -2
  57. package/dist/{chunk-CFLVPV5M.js → chunk-QC42MLAK.js} +7 -2
  58. package/dist/chunk-QC42MLAK.js.map +1 -0
  59. package/dist/chunk-RDXBMTP5.js +32 -0
  60. package/dist/chunk-RDXBMTP5.js.map +1 -0
  61. package/dist/chunk-SFZNIO6U.js +18 -0
  62. package/dist/chunk-SFZNIO6U.js.map +1 -0
  63. package/dist/chunk-U7KURWW3.js +840 -0
  64. package/dist/chunk-U7KURWW3.js.map +1 -0
  65. package/dist/chunk-WVE3F724.js +200 -0
  66. package/dist/chunk-WVE3F724.js.map +1 -0
  67. package/dist/{chunk-FJ5RSSMA.js → chunk-XAU7QFG3.js} +178 -36
  68. package/dist/chunk-XAU7QFG3.js.map +1 -0
  69. package/dist/chunk-Y6S4OVVQ.js +16 -0
  70. package/dist/chunk-Y6S4OVVQ.js.map +1 -0
  71. package/dist/chunk-ZKNUMH2M.js +119 -0
  72. package/dist/chunk-ZKNUMH2M.js.map +1 -0
  73. package/dist/chunk-ZTMKFZQ3.js +13214 -0
  74. package/dist/chunk-ZTMKFZQ3.js.map +1 -0
  75. package/dist/{createTrueFoundryServer-B72bU-J7.d.ts → createTrueFoundryServer-CmZnBh_l.d.ts} +15 -4
  76. package/dist/index.d.ts +1002 -22
  77. package/dist/index.js +689 -67
  78. package/dist/index.js.map +1 -1
  79. package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +552 -8
  80. package/dist/plugins/trueforge-agent-server-adapter/index.js +503 -188
  81. package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
  82. package/dist/styles.css +1 -1
  83. package/package.json +8 -7
  84. package/dist/DrawerLayout-Q6UK4VMI.js +0 -159
  85. package/dist/DrawerLayout-Q6UK4VMI.js.map +0 -1
  86. package/dist/OpenUiFenceBlock-6UIIAVBX.js +0 -9
  87. package/dist/SettingsBuilder-WF7ZWKQW.js.map +0 -1
  88. package/dist/ShellRouteSync-T4WLY57Q.js.map +0 -1
  89. package/dist/SidebarLayout-3WZ3CVON.js +0 -256
  90. package/dist/SidebarLayout-3WZ3CVON.js.map +0 -1
  91. package/dist/WidgetLayout-3QZ357FL.js.map +0 -1
  92. package/dist/chunk-36KOSC2J.js +0 -567
  93. package/dist/chunk-36KOSC2J.js.map +0 -1
  94. package/dist/chunk-3S6KHO7H.js +0 -2121
  95. package/dist/chunk-3S6KHO7H.js.map +0 -1
  96. package/dist/chunk-7L63OK3O.js +0 -91
  97. package/dist/chunk-7L63OK3O.js.map +0 -1
  98. package/dist/chunk-CFLVPV5M.js.map +0 -1
  99. package/dist/chunk-FJ5RSSMA.js.map +0 -1
  100. package/dist/chunk-OSV3HI5M.js +0 -6891
  101. package/dist/chunk-OSV3HI5M.js.map +0 -1
  102. package/dist/chunk-WQULF5AT.js +0 -460
  103. package/dist/chunk-WQULF5AT.js.map +0 -1
  104. package/dist/chunk-WREC7D54.js.map +0 -1
  105. package/dist/chunk-YIWUG6MC.js +0 -101
  106. package/dist/chunk-YIWUG6MC.js.map +0 -1
  107. package/dist/chunk-ZXOADNF3.js +0 -75
  108. package/dist/chunk-ZXOADNF3.js.map +0 -1
  109. /package/dist/{OpenUiFenceBlock-6UIIAVBX.js.map → AgentMetricChart-JPU3MFQ2.js.map} +0 -0
  110. /package/dist/{chunk-B52K63AW.js.map → chunk-MPNSO7E6.js.map} +0 -0
@@ -1,195 +1,114 @@
1
1
  import {
2
2
  createTrueFoundryServer
3
- } from "../../chunk-CFLVPV5M.js";
3
+ } from "../../chunk-QC42MLAK.js";
4
+ import {
5
+ drainListPages
6
+ } from "../../chunk-SFZNIO6U.js";
7
+ import {
8
+ readSessionIsCreateAgent
9
+ } from "../../chunk-RDXBMTP5.js";
4
10
 
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");
11
+ // src/plugins/trueforge-agent-server-adapter/client.ts
12
+ import { TrueForge } from "@truefoundry/trueforge-sdk";
13
+ var DEFAULT_BASE_URL = "/";
14
+ function resolveTrueForgeBaseUrl(baseUrl) {
15
+ if (/^https?:\/\//i.test(baseUrl)) return baseUrl;
16
+ const origin = globalThis.location?.origin;
17
+ if (typeof origin === "string" && origin.length > 0 && origin !== "null") {
18
+ return new URL(baseUrl, origin).href;
30
19
  }
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
- description: server.description,
41
- ...server.logo === void 0 ? {} : { logo: server.logo },
42
- auth: toUiAuthPublic(server.auth)
43
- };
20
+ return baseUrl;
44
21
  }
45
- function toUiTool(tool) {
46
- const name = typeof tool.name === "string" && tool.name !== "" ? tool.name : "tool";
47
- const description = typeof tool.description === "string" ? tool.description : "";
48
- return { id: name, name, description };
49
- }
50
- function toUiConnector(server) {
51
- const auth = toUiAuthPublic(server.manifest.auth);
52
- return {
53
- id: server.name,
54
- name: server.name,
55
- description: server.manifest.description,
56
- url: server.manifest.url,
57
- auth,
58
- requiresAuth: server.authStatus.status === "auth_required",
59
- authenticated: server.authStatus.status !== "auth_required"
60
- };
61
- }
62
- function toUiConnectorFromReadEntry(server) {
63
- const auth = server.auth?.type ? { type: server.auth.type } : { type: "none" };
64
- return {
65
- id: server.name,
66
- name: server.name,
67
- description: server.url,
68
- url: server.url,
69
- auth,
70
- requiresAuth: server.authStatus.status === "auth_required",
71
- authenticated: server.authStatus.status !== "auth_required"
72
- };
73
- }
74
- function toHarnessManifest(req) {
75
- const auth = toHarnessAuth(req.auth);
76
- const trimmed = req.description?.trim();
77
- return {
78
- type: "remote",
79
- name: req.name,
80
- url: req.url,
81
- description: trimmed !== void 0 && trimmed !== "" ? trimmed : `${req.name} MCP server`,
82
- ...auth === void 0 ? {} : { auth }
83
- };
22
+ function createTrueForgeClient(options = {}) {
23
+ return new TrueForge({
24
+ baseUrl: resolveTrueForgeBaseUrl(options.baseUrl ?? DEFAULT_BASE_URL),
25
+ ...options.token === void 0 ? {} : { token: options.token },
26
+ ...options.fetch === void 0 ? {} : { fetch: options.fetch }
27
+ });
84
28
  }
85
- function createConnectorCatalog(client) {
86
- async function getConfigured(name) {
87
- const listed = await client.settings.mcpServers.list();
88
- const existing = listed.data.find((server) => server.name === name);
89
- if (existing === void 0) {
90
- throw new Error(`MCP server "${name}" not found`);
91
- }
92
- return existing;
29
+ function parseIsoDate(value) {
30
+ const date = new Date(value);
31
+ if (Number.isNaN(date.getTime())) {
32
+ throw new Error(`Invalid ISO timestamp: ${value}`);
93
33
  }
94
- async function resolveWriteAuth(req) {
95
- if (req.auth.type !== "header") {
96
- return req.auth;
97
- }
98
- const apiKey = req.auth.apiKey?.trim();
99
- if (apiKey !== void 0 && apiKey !== "") {
100
- return req.auth;
101
- }
102
- if (req.id === void 0) {
103
- throw new Error("API key is required for header-authenticated MCP servers");
104
- }
105
- const existing = await getConfigured(req.id);
106
- if (existing.manifest.auth?.type !== "header") {
107
- throw new Error(`MCP server "${req.id}" has no stored header credentials to reuse`);
108
- }
109
- const preferredHeader = req.auth.headerName?.trim();
110
- const storedHeaderName = Object.keys(existing.manifest.auth.headers)[0];
111
- const headerName = preferredHeader !== void 0 && preferredHeader !== "" ? preferredHeader : storedHeaderName ?? DEFAULT_API_KEY_HEADER;
112
- const stored = existing.manifest.auth.headers[headerName] ?? Object.values(existing.manifest.auth.headers)[0];
113
- if (stored === void 0) {
114
- throw new Error(`MCP server "${req.id}" has no stored header credentials to reuse`);
115
- }
116
- return { type: "header", apiKey: stored, headerName };
34
+ return date;
35
+ }
36
+
37
+ // src/plugins/trueforge-agent-server-adapter/agentMetricsServer.ts
38
+ function toHarnessChartName(name) {
39
+ if (name === "sessions_over_time" || name === "sessions_cost_over_time" || name === "turns_over_time") {
40
+ return name;
117
41
  }
42
+ throw new Error(`Unsupported Harness metrics chart: ${name}`);
43
+ }
44
+ function createHarnessAgentMetricsServer(options = {}) {
45
+ const client = options.client ?? createTrueForgeClient(options);
118
46
  return {
119
- getConnectorCatalog: async () => {
120
- const body = await client.catalogs.mcpServers.list();
121
- return body.data.map(toUiCatalogEntry);
47
+ async getCharts() {
48
+ const { data } = await client.internal.metrics.listCharts();
49
+ return data.charts;
122
50
  },
123
- getConnector: async (req) => {
124
- const body = await client.settings.mcpServers.get(req.id);
125
- return toUiConnector(body.data);
126
- },
127
- listConnectors: async (req) => {
128
- const body = await client.settings.mcpServers.list();
129
- const connectors = body.data.map(toUiConnector);
130
- const query = req?.query?.trim().toLowerCase();
131
- if (query === void 0 || query === "") {
132
- return connectors;
133
- }
134
- return connectors.filter(
135
- (connector) => connector.name.toLowerCase().includes(query) || connector.description.toLowerCase().includes(query) || connector.url.toLowerCase().includes(query)
136
- );
137
- },
138
- getToolsByConnectorId: async ({ id }) => {
139
- const body = await client.mcpServers.listTools(id);
140
- return body.data.map(toUiTool);
141
- },
142
- createConnector: async (req) => {
143
- const auth = await resolveWriteAuth({ auth: req.auth });
144
- const body = await client.settings.mcpServers.create({
145
- manifest: toHarnessManifest({
146
- name: req.name,
147
- url: req.url,
148
- auth,
149
- description: req.description
150
- })
51
+ async getMeters({ agentId, startTimestamp, endTimestamp }) {
52
+ const { data } = await client.internal.metrics.getMeters({
53
+ agentId,
54
+ startTimestamp: parseIsoDate(startTimestamp),
55
+ endTimestamp: parseIsoDate(endTimestamp)
151
56
  });
152
- return toUiConnector(body.data);
57
+ return data.meters;
153
58
  },
154
- updateConnector: async (req) => {
155
- const auth = await resolveWriteAuth({ id: req.id, auth: req.auth });
156
- const body = await client.settings.mcpServers.createOrUpdate({
157
- manifest: toHarnessManifest({
158
- name: req.id,
159
- url: req.url,
160
- auth,
161
- description: req.description
162
- })
59
+ async getChartData({ agentId, startTimestamp, endTimestamp, chartName }) {
60
+ const { data } = await client.internal.metrics.getChartData({
61
+ agentId,
62
+ startTimestamp: parseIsoDate(startTimestamp),
63
+ endTimestamp: parseIsoDate(endTimestamp),
64
+ chartName: toHarnessChartName(chartName)
163
65
  });
164
- return toUiConnector(body.data);
165
- },
166
- authenticateConnector: async (req) => {
167
- const result = await client.mcpServers.authorize(
168
- req.id,
169
- req.returnTo === void 0 ? {} : { returnTo: req.returnTo }
170
- );
171
- return { status: result.status, authorization_endpoint: result.authorizationUrl };
172
- },
173
- disconnectConnector: async (req) => {
174
- const existing = await getConfigured(req.id);
175
- if (existing.manifest.auth?.type !== "dcr") {
176
- throw new Error(`Disconnect is only supported for OAuth MCP servers`);
177
- }
178
- const body = await client.mcpServers.deleteAuthorization(req.id);
179
- return toUiConnector(body.data);
66
+ return data;
180
67
  }
181
68
  };
182
69
  }
183
70
 
184
- // src/plugins/trueforge-agent-server-adapter/client.ts
185
- import { TrueForge } from "@truefoundry/trueforge-sdk";
186
- var DEFAULT_BASE_URL = "/";
187
- function createTrueForgeClient(options = {}) {
188
- return new TrueForge({
189
- baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
190
- ...options.token === void 0 ? {} : { token: options.token },
191
- ...options.fetch === void 0 ? {} : { fetch: options.fetch }
192
- });
71
+ // src/plugins/trueforge-agent-server-adapter/toUiTurnState.ts
72
+ function toUiTurnDoneMetrics(metrics) {
73
+ return {
74
+ totalInputTokens: metrics.totalInputTokens ?? 0,
75
+ totalOutputTokens: metrics.totalOutputTokens ?? 0,
76
+ totalTokens: metrics.totalTokens ?? 0,
77
+ totalCacheReadTokens: metrics.totalCacheReadTokens ?? 0,
78
+ totalCacheWriteTokens: metrics.totalCacheWriteTokens ?? 0,
79
+ totalReasoningTokens: metrics.totalReasoningTokens ?? 0,
80
+ ...metrics.totalCostInUsd == null ? {} : { totalCostInUsd: metrics.totalCostInUsd }
81
+ };
82
+ }
83
+ function toUiTurnState(state) {
84
+ return state.status === "running" ? { status: "running" } : toUiTerminalTurnState(state);
85
+ }
86
+ function toUiTerminalTurnState(state) {
87
+ switch (state.status) {
88
+ case "cancelled":
89
+ return { status: "cancelled", reason: state.reason, completedAt: state.completedAt };
90
+ case "error":
91
+ return { status: "error", message: state.message, completedAt: state.completedAt };
92
+ case "done":
93
+ return {
94
+ status: "done",
95
+ completedAt: state.completedAt,
96
+ requiredActions: state.requiredActions,
97
+ ...state.output == null ? {} : { output: state.output },
98
+ ...state.metrics == null ? {} : { metrics: toUiTurnDoneMetrics(state.metrics) }
99
+ };
100
+ }
101
+ }
102
+ function toUiSessionEvent(event) {
103
+ if (event.type !== "turn.done") return { ...event };
104
+ return { ...event, state: toUiTerminalTurnState(event.state) };
105
+ }
106
+ function toUiStreamingEvent(event) {
107
+ if (event.type !== "turn.done") return { ...event };
108
+ return { ...event, state: toUiTerminalTurnState(event.state) };
109
+ }
110
+ function toUiEventItem(item) {
111
+ return { turnId: item.turnId, event: toUiSessionEvent(item.event) };
193
112
  }
194
113
 
195
114
  // src/plugins/trueforge-agent-server-adapter/chatServer.ts
@@ -228,6 +147,7 @@ function toUiSession(session) {
228
147
  return {
229
148
  id: session.id,
230
149
  isMutable: session.agent.type === "inline",
150
+ isCreateAgent: readSessionIsCreateAgent(session.metadata),
231
151
  createdAt: session.createdAt,
232
152
  updatedAt: session.updatedAt,
233
153
  ...session.title === null ? {} : { title: session.title },
@@ -237,6 +157,10 @@ function toUiSession(session) {
237
157
  ...session.agent.type === "inline" ? { agentSpec: toUiAgentSpec(session.agent.spec) } : {}
238
158
  };
239
159
  }
160
+ function createSessionMetadata(request) {
161
+ if (request.metadata === void 0) return void 0;
162
+ return request.metadata;
163
+ }
240
164
  function toUiContent(content) {
241
165
  return typeof content === "string" ? content : content.map((part) => ({ ...part }));
242
166
  }
@@ -244,16 +168,14 @@ function toUiInput(input) {
244
168
  return input.map((item) => item.type === "user.message" ? { ...item, content: toUiContent(item.content) } : item);
245
169
  }
246
170
  function toUiTurn(turn) {
247
- const { previousTurnId, input, ...rest } = turn;
171
+ const { previousTurnId, input, state, ...rest } = turn;
248
172
  return {
249
173
  ...rest,
174
+ state: toUiTurnState(state),
250
175
  ...previousTurnId === null ? {} : { previousTurnId },
251
176
  ...input === void 0 ? {} : { input: toUiInput(input) }
252
177
  };
253
178
  }
254
- function toUiEventItem(item) {
255
- return { turnId: item.turnId, event: { ...item.event } };
256
- }
257
179
  function toListResult(page, map) {
258
180
  const data = page.data.map(map);
259
181
  const token = page.response.pagination.nextPageToken;
@@ -293,15 +215,18 @@ function createHarnessChatServer(options = {}) {
293
215
  return response.blob();
294
216
  },
295
217
  async createSession(request) {
218
+ const metadata = createSessionMetadata(request);
296
219
  if (request.agentName !== void 0 && request.agentName.length > 0) {
297
220
  const created = await client.sessions.create({
298
- agent: { name: request.agentName }
221
+ agent: { name: request.agentName },
222
+ ...metadata === void 0 ? {} : { metadata }
299
223
  });
300
224
  return toUiSession(created.data);
301
225
  }
302
226
  if (request.agentSpec !== void 0) {
303
227
  const created = await client.sessions.create({
304
- agent: { spec: toHarnessAgentSpec(request.agentSpec) }
228
+ agent: { spec: toHarnessAgentSpec(request.agentSpec) },
229
+ ...metadata === void 0 ? {} : { metadata }
305
230
  });
306
231
  return toUiSession(created.data);
307
232
  }
@@ -342,7 +267,7 @@ function createHarnessChatServer(options = {}) {
342
267
  for await (const item of stream.withMetadata()) {
343
268
  yield {
344
269
  sequenceNumber: sequenceNumber(item.id, fallbackSequence),
345
- event: { ...item.data }
270
+ event: toUiStreamingEvent(item.data)
346
271
  };
347
272
  fallbackSequence += 1;
348
273
  }
@@ -360,7 +285,7 @@ function createHarnessChatServer(options = {}) {
360
285
  for await (const item of stream.withMetadata()) {
361
286
  yield {
362
287
  sequenceNumber: sequenceNumber(item.id, fallbackSequence),
363
- event: { ...item.data }
288
+ event: toUiStreamingEvent(item.data)
364
289
  };
365
290
  fallbackSequence += 1;
366
291
  }
@@ -390,14 +315,256 @@ function createHarnessChatServer(options = {}) {
390
315
  };
391
316
  }
392
317
 
318
+ // src/plugins/trueforge-agent-server-adapter/agentSessionsServer.ts
319
+ function toSessionListEntry(session) {
320
+ return {
321
+ id: session.id,
322
+ createdAt: session.createdAt,
323
+ updatedAt: session.updatedAt,
324
+ lastActivityAt: session.updatedAt,
325
+ isCreateAgent: readSessionIsCreateAgent(session.metadata),
326
+ isMutable: session.agent.type === "inline",
327
+ metrics: {
328
+ totalTurns: session.metrics.totalTurns,
329
+ totalCostInUsd: session.metrics.totalCostInUsd,
330
+ totalDurationMs: session.metrics.totalDurationMs
331
+ },
332
+ ...session.title === null ? {} : { title: session.title },
333
+ ...session.agent.type === "reference" && session.agent.name !== null ? { agentName: session.agent.name } : {},
334
+ ...session.agent.type === "inline" ? { agentSpec: toUiAgentSpec(session.agent.spec) } : {}
335
+ };
336
+ }
337
+ function createHarnessAgentSessionsServer(options = {}) {
338
+ const client = options.client ?? createTrueForgeClient(options);
339
+ return {
340
+ async getAgent({ agentId }) {
341
+ const { data } = await client.agents.get(agentId);
342
+ return {
343
+ agentId: data.id,
344
+ name: data.name,
345
+ agentSpec: toUiAgentSpec(data.manifest)
346
+ };
347
+ },
348
+ async getCodeSnippets({ agentId }) {
349
+ const { data } = await client.internal.agents.getCodeSnippets(agentId);
350
+ return data.snippets;
351
+ },
352
+ async listSessions(requestParams = {}) {
353
+ const page = await client.sessions.list({
354
+ ...requestParams.limit === void 0 ? {} : { limit: requestParams.limit },
355
+ ...requestParams.order === void 0 ? {} : { order: requestParams.order },
356
+ ...requestParams.pageToken === void 0 ? {} : { pageToken: requestParams.pageToken },
357
+ ...requestParams.startTimestamp === void 0 ? {} : { startTimestamp: parseIsoDate(requestParams.startTimestamp) },
358
+ ...requestParams.endTimestamp === void 0 ? {} : { endTimestamp: parseIsoDate(requestParams.endTimestamp) },
359
+ ...requestParams.agentId === void 0 || requestParams.agentId.length === 0 ? {} : { agentId: requestParams.agentId }
360
+ });
361
+ return toListResult(page, toSessionListEntry);
362
+ },
363
+ async listSessionEvents({ sessionId, pageToken, limit }) {
364
+ const page = await client.sessions.listEvents(sessionId, {
365
+ ...pageToken === void 0 ? {} : { pageToken },
366
+ ...limit === void 0 ? {} : { limit }
367
+ });
368
+ return toListResult(page, toUiEventItem);
369
+ }
370
+ };
371
+ }
372
+
373
+ // src/plugins/trueforge-agent-server-adapter/catalogs/connectorCatalog.ts
374
+ var DEFAULT_API_KEY_HEADER = "Authorization";
375
+ function toUiAuthPublic(auth) {
376
+ if (auth === void 0) {
377
+ return { type: "none" };
378
+ }
379
+ if (auth.type === "dcr") {
380
+ return { type: "dcr" };
381
+ }
382
+ const headerName = Object.keys(auth.headers)[0];
383
+ return {
384
+ type: "header",
385
+ ...headerName === void 0 ? {} : { headerName }
386
+ };
387
+ }
388
+ function toHarnessAuth(auth) {
389
+ if (auth.type === "none") {
390
+ return void 0;
391
+ }
392
+ if (auth.type === "dcr") {
393
+ return { type: "dcr" };
394
+ }
395
+ const apiKey = auth.apiKey?.trim();
396
+ if (apiKey === void 0 || apiKey === "") {
397
+ throw new Error("API key is required for header-authenticated MCP servers");
398
+ }
399
+ const trimmedHeader = auth.headerName?.trim();
400
+ const headerName = trimmedHeader !== void 0 && trimmedHeader !== "" ? trimmedHeader : DEFAULT_API_KEY_HEADER;
401
+ return { type: "header", headers: { [headerName]: apiKey } };
402
+ }
403
+ function toUiCatalogEntry(server) {
404
+ return {
405
+ id: server.name,
406
+ name: server.name,
407
+ url: server.url,
408
+ description: server.description,
409
+ ...server.logo === void 0 ? {} : { logo: server.logo },
410
+ auth: toUiAuthPublic(server.auth)
411
+ };
412
+ }
413
+ function toUiTool(tool) {
414
+ const name = typeof tool.name === "string" && tool.name !== "" ? tool.name : "tool";
415
+ const description = typeof tool.description === "string" ? tool.description : "";
416
+ return { id: name, name, description };
417
+ }
418
+ function toUiConnector(server) {
419
+ const auth = toUiAuthPublic(server.manifest.auth);
420
+ return {
421
+ id: server.name,
422
+ name: server.name,
423
+ description: server.manifest.description,
424
+ url: server.manifest.url,
425
+ auth,
426
+ requiresAuth: server.authStatus.status === "auth_required",
427
+ authenticated: server.authStatus.status !== "auth_required"
428
+ };
429
+ }
430
+ function toUiConnectorFromReadEntry(server) {
431
+ const auth = server.auth?.type ? { type: server.auth.type } : { type: "none" };
432
+ return {
433
+ id: server.name,
434
+ name: server.name,
435
+ description: server.url,
436
+ url: server.url,
437
+ auth,
438
+ requiresAuth: server.authStatus.status === "auth_required",
439
+ authenticated: server.authStatus.status !== "auth_required"
440
+ };
441
+ }
442
+ function toHarnessManifest(req) {
443
+ const auth = toHarnessAuth(req.auth);
444
+ const trimmed = req.description?.trim();
445
+ return {
446
+ type: "remote",
447
+ name: req.name,
448
+ url: req.url,
449
+ description: trimmed !== void 0 && trimmed !== "" ? trimmed : `${req.name} MCP server`,
450
+ ...auth === void 0 ? {} : { auth }
451
+ };
452
+ }
453
+ function createConnectorCatalog(client) {
454
+ async function getConfigured(name) {
455
+ const listed = await client.settings.mcpServers.list();
456
+ const existing = listed.data.find((server) => server.name === name);
457
+ if (existing === void 0) {
458
+ throw new Error(`MCP server "${name}" not found`);
459
+ }
460
+ return existing;
461
+ }
462
+ async function resolveWriteAuth(req) {
463
+ if (req.auth.type !== "header") {
464
+ return req.auth;
465
+ }
466
+ const apiKey = req.auth.apiKey?.trim();
467
+ if (apiKey !== void 0 && apiKey !== "") {
468
+ return req.auth;
469
+ }
470
+ if (req.id === void 0) {
471
+ throw new Error("API key is required for header-authenticated MCP servers");
472
+ }
473
+ const existing = await getConfigured(req.id);
474
+ if (existing.manifest.auth?.type !== "header") {
475
+ throw new Error(`MCP server "${req.id}" has no stored header credentials to reuse`);
476
+ }
477
+ const preferredHeader = req.auth.headerName?.trim();
478
+ const storedHeaderName = Object.keys(existing.manifest.auth.headers)[0];
479
+ const headerName = preferredHeader !== void 0 && preferredHeader !== "" ? preferredHeader : storedHeaderName ?? DEFAULT_API_KEY_HEADER;
480
+ const stored = existing.manifest.auth.headers[headerName] ?? Object.values(existing.manifest.auth.headers)[0];
481
+ if (stored === void 0) {
482
+ throw new Error(`MCP server "${req.id}" has no stored header credentials to reuse`);
483
+ }
484
+ return { type: "header", apiKey: stored, headerName };
485
+ }
486
+ return {
487
+ getConnectorCatalog: async () => {
488
+ const body = await client.catalogs.mcpServers.list();
489
+ return body.data.map(toUiCatalogEntry);
490
+ },
491
+ getConnector: async (req) => {
492
+ const body = await client.settings.mcpServers.get(req.id);
493
+ return toUiConnector(body.data);
494
+ },
495
+ listConnectors: async (req) => {
496
+ const body = await client.settings.mcpServers.list();
497
+ const connectors = body.data.map(toUiConnector);
498
+ const query = req?.query?.trim().toLowerCase();
499
+ if (query === void 0 || query === "") {
500
+ return connectors;
501
+ }
502
+ return connectors.filter(
503
+ (connector) => connector.name.toLowerCase().includes(query) || connector.description.toLowerCase().includes(query) || connector.url.toLowerCase().includes(query)
504
+ );
505
+ },
506
+ getToolsByConnectorId: async ({ id }) => {
507
+ const body = await client.mcpServers.listTools(id);
508
+ return body.data.map(toUiTool);
509
+ },
510
+ createConnector: async (req) => {
511
+ const auth = await resolveWriteAuth({ auth: req.auth });
512
+ const body = await client.settings.mcpServers.create({
513
+ manifest: toHarnessManifest({
514
+ name: req.name,
515
+ url: req.url,
516
+ auth,
517
+ description: req.description
518
+ })
519
+ });
520
+ return toUiConnector(body.data);
521
+ },
522
+ updateConnector: async (req) => {
523
+ const auth = await resolveWriteAuth({ id: req.id, auth: req.auth });
524
+ const body = await client.settings.mcpServers.createOrUpdate({
525
+ manifest: toHarnessManifest({
526
+ name: req.id,
527
+ url: req.url,
528
+ auth,
529
+ description: req.description
530
+ })
531
+ });
532
+ return toUiConnector(body.data);
533
+ },
534
+ authenticateConnector: async (req) => {
535
+ const result = await client.mcpServers.authorize(
536
+ req.id,
537
+ req.returnTo === void 0 ? {} : { returnTo: req.returnTo }
538
+ );
539
+ return { status: result.status, authorization_endpoint: result.authorizationUrl };
540
+ },
541
+ disconnectConnector: async (req) => {
542
+ const existing = await getConfigured(req.id);
543
+ if (existing.manifest.auth?.type !== "dcr") {
544
+ throw new Error(`Disconnect is only supported for OAuth MCP servers`);
545
+ }
546
+ const body = await client.mcpServers.deleteAuthorization(req.id);
547
+ return toUiConnector(body.data);
548
+ }
549
+ };
550
+ }
551
+
393
552
  // src/plugins/trueforge-agent-server-adapter/lists.ts
394
553
  async function listModels(client) {
395
554
  const body = await client.models.list();
396
555
  return body.data;
397
556
  }
557
+ async function listConfiguredMcpServersPage(client, req = {}) {
558
+ const page = await client.mcpServers.list({
559
+ ...req.limit === void 0 ? {} : { limit: req.limit },
560
+ ...req.pageToken === void 0 ? {} : { pageToken: req.pageToken }
561
+ });
562
+ return toListResult(page, (server) => server);
563
+ }
398
564
  async function listConfiguredMcpServers(client) {
399
- const body = await client.mcpServers.list();
400
- return body.data;
565
+ return drainListPages({
566
+ fetchPage: (pageToken) => listConfiguredMcpServersPage(client, { pageToken })
567
+ });
401
568
  }
402
569
  async function listSkills(client) {
403
570
  const body = await client.skills.list();
@@ -423,7 +590,7 @@ function toModelSelection({
423
590
  model,
424
591
  logo
425
592
  }) {
426
- const efforts = model.properties.reasoningEfforts;
593
+ const { contextLength, maxOutputTokens, reasoningEfforts } = model.properties;
427
594
  return {
428
595
  id: model.modelId,
429
596
  name: model.name,
@@ -432,7 +599,9 @@ function toModelSelection({
432
599
  ...logo === void 0 ? {} : { logo }
433
600
  },
434
601
  properties: {
435
- ...efforts !== void 0 && efforts.length > 0 ? { reasoningEfforts: [...efforts] } : {}
602
+ ...contextLength === void 0 ? {} : { contextLength },
603
+ ...maxOutputTokens === void 0 ? {} : { maxOutputTokens },
604
+ ...reasoningEfforts === void 0 ? {} : { reasoningEfforts: [...reasoningEfforts] }
436
605
  }
437
606
  };
438
607
  }
@@ -467,6 +636,19 @@ function createHarnessBuilderServer(options = {}) {
467
636
  return skills.map((skill) => ({ id: skill.name, name: skill.name, description: skill.description }));
468
637
  },
469
638
  getMcp: async () => (await listConfiguredMcpServers(client)).map(toUiConnectorFromReadEntry),
639
+ listMcp: async (req) => {
640
+ const page = await listConfiguredMcpServersPage(client, req ?? {});
641
+ return {
642
+ data: page.data.map(toUiConnectorFromReadEntry),
643
+ ...page.nextPageToken === void 0 ? {} : { nextPageToken: page.nextPageToken }
644
+ };
645
+ },
646
+ getMcpTools: async ({ connectorId }) => {
647
+ const body = await client.mcpServers.listTools(connectorId);
648
+ return body.data.flatMap(
649
+ (tool) => typeof tool.name === "string" && tool.name.trim() !== "" ? [toUiTool(tool)] : []
650
+ );
651
+ },
470
652
  async searchAgents(req) {
471
653
  const { data } = await client.agents.list();
472
654
  const query = req?.query?.trim().toLowerCase();
@@ -488,6 +670,12 @@ function createHarnessBuilderServer(options = {}) {
488
670
  }
489
671
  const created = await client.agents.create({ name: agentName, manifest });
490
672
  return { agentId: created.data.id };
673
+ },
674
+ async deleteAgent({ agentName }) {
675
+ const { data } = await client.agents.list();
676
+ const existing = data.find((agent) => agent.name === agentName);
677
+ if (!existing) return;
678
+ await client.agents.delete(existing.id);
491
679
  }
492
680
  };
493
681
  }
@@ -817,6 +1005,126 @@ function createSkillCatalog(client) {
817
1005
  };
818
1006
  }
819
1007
 
1008
+ // src/plugins/trueforge-agent-server-adapter/schedules/scheduleServer.ts
1009
+ var SCHEDULES_PAGE_LIMIT = 25;
1010
+ async function loadAgentIndex(client) {
1011
+ const { data } = await client.agents.list();
1012
+ const idToName = /* @__PURE__ */ new Map();
1013
+ const nameToId = /* @__PURE__ */ new Map();
1014
+ for (const agent of data) {
1015
+ idToName.set(agent.id, agent.name);
1016
+ nameToId.set(agent.name, agent.id);
1017
+ }
1018
+ return { idToName, nameToId };
1019
+ }
1020
+ function resolveAgentName(agentId, index) {
1021
+ const byId = index.idToName.get(agentId);
1022
+ if (byId != null) return byId;
1023
+ if (index.nameToId.has(agentId)) return agentId;
1024
+ throw new Error(`Unknown agent: ${agentId}`);
1025
+ }
1026
+ function collectAgentIds(req) {
1027
+ const ids = [];
1028
+ if (req?.agentIds != null) {
1029
+ for (const id of req.agentIds) {
1030
+ if (id !== "") ids.push(id);
1031
+ }
1032
+ }
1033
+ if (req?.agentId != null && req.agentId !== "") ids.push(req.agentId);
1034
+ return [...new Set(ids)];
1035
+ }
1036
+ function wireStatus(manifest) {
1037
+ return manifest.status ?? "active";
1038
+ }
1039
+ function toUiSchedule(wire, index) {
1040
+ const agentId = index.nameToId.get(wire.agentName) ?? wire.agentName;
1041
+ return {
1042
+ id: wire.id,
1043
+ name: wire.name,
1044
+ agentId,
1045
+ agentName: wire.agentName,
1046
+ task: wire.manifest.task,
1047
+ cron: wire.manifest.cron,
1048
+ timezone: wire.manifest.timezone ?? "UTC",
1049
+ status: wireStatus(wire.manifest),
1050
+ lastRunAt: null
1051
+ };
1052
+ }
1053
+ function toWireManifest(input) {
1054
+ return {
1055
+ task: input.task,
1056
+ cron: input.cron,
1057
+ timezone: input.timezone ?? "UTC",
1058
+ status: input.status ?? "active"
1059
+ };
1060
+ }
1061
+ function toIsoInstant(value) {
1062
+ if (value instanceof Date) return value.toISOString();
1063
+ return value;
1064
+ }
1065
+ function toUiScheduleRun(wire) {
1066
+ return {
1067
+ id: wire.id,
1068
+ scheduleId: wire.scheduleId,
1069
+ name: wire.name,
1070
+ scheduledFor: toIsoInstant(wire.scheduledFor),
1071
+ status: wire.status,
1072
+ triggeredAt: wire.triggeredAt == null ? null : toIsoInstant(wire.triggeredAt),
1073
+ triggeredBy: wire.createdBySubject.subjectDisplayName || wire.createdBySubject.subjectId
1074
+ };
1075
+ }
1076
+ function createScheduleServer(options) {
1077
+ const { client } = options;
1078
+ return {
1079
+ async listSchedules(req) {
1080
+ const index = await loadAgentIndex(client);
1081
+ const agentIds = collectAgentIds(req);
1082
+ const agentNames = agentIds.length === 0 ? void 0 : agentIds.map((id) => resolveAgentName(id, index)).join(",");
1083
+ const limit = Math.min(Math.max(req?.limit ?? SCHEDULES_PAGE_LIMIT, 1), SCHEDULES_PAGE_LIMIT);
1084
+ const page = await client.schedules.list({
1085
+ limit,
1086
+ ...req?.pageToken === void 0 || req.pageToken === "" ? {} : { pageToken: req.pageToken },
1087
+ ...agentNames === void 0 ? {} : { agentNames }
1088
+ });
1089
+ return toListResult(page, (row) => toUiSchedule(row, index));
1090
+ },
1091
+ async getSchedule({ id }) {
1092
+ const index = await loadAgentIndex(client);
1093
+ const { data } = await client.schedules.get(id);
1094
+ return toUiSchedule(data, index);
1095
+ },
1096
+ async createSchedule(req) {
1097
+ const index = await loadAgentIndex(client);
1098
+ const agentName = resolveAgentName(req.agentId, index);
1099
+ const { data } = await client.schedules.create({
1100
+ agentName,
1101
+ name: req.name,
1102
+ manifest: toWireManifest(req)
1103
+ });
1104
+ return toUiSchedule(data, index);
1105
+ },
1106
+ async updateSchedule(req) {
1107
+ const index = await loadAgentIndex(client);
1108
+ const { data } = await client.schedules.update(req.id, {
1109
+ name: req.name,
1110
+ manifest: toWireManifest(req)
1111
+ });
1112
+ return toUiSchedule(data, index);
1113
+ },
1114
+ async deleteSchedule({ id }) {
1115
+ await client.schedules.delete(id);
1116
+ },
1117
+ async listScheduleRuns({ scheduleId }) {
1118
+ const { data } = await client.schedules.listRuns(scheduleId);
1119
+ return data.map(toUiScheduleRun);
1120
+ },
1121
+ async createScheduleRun(req) {
1122
+ const { data } = await client.schedules.createRun({ scheduleId: req.scheduleId });
1123
+ return toUiScheduleRun(data);
1124
+ }
1125
+ };
1126
+ }
1127
+
820
1128
  // src/plugins/trueforge-agent-server-adapter/index.ts
821
1129
  function createTrueForgeAgentUIServer(options = {}) {
822
1130
  const { catalog: catalogOverride, ...clientOptions } = options;
@@ -830,22 +1138,29 @@ function createTrueForgeAgentUIServer(options = {}) {
830
1138
  return createTrueFoundryServer({
831
1139
  chatServer: createHarnessChatServer({ client }),
832
1140
  ...createHarnessBuilderServer({ client }),
833
- catalog
1141
+ catalog,
1142
+ sessions: createHarnessAgentSessionsServer({ ...clientOptions, client }),
1143
+ metrics: createHarnessAgentMetricsServer({ ...clientOptions, client }),
1144
+ schedules: createScheduleServer({ client })
834
1145
  });
835
1146
  }
836
1147
  export {
837
1148
  configFromHarness,
838
1149
  createConnectorCatalog,
1150
+ createHarnessAgentMetricsServer,
1151
+ createHarnessAgentSessionsServer,
839
1152
  createHarnessBuilderServer,
840
1153
  createHarnessChatServer,
841
1154
  createModelProviderCatalog,
842
1155
  createSandboxProviderCatalog,
1156
+ createScheduleServer,
843
1157
  createSkillCatalog,
844
1158
  createTrueForgeAgentUIServer,
845
1159
  createTrueForgeClient,
846
1160
  filterUiSandboxProviders,
847
1161
  getCapabilities,
848
1162
  listConfiguredMcpServers,
1163
+ listConfiguredMcpServersPage,
849
1164
  listModels,
850
1165
  listSkills,
851
1166
  modelProviderLogosByName,