@truefoundry/trueforge-ui 0.2.4 → 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 (113) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +55 -23
  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-ODC3LVHN.js → ConnectorSettings-MXFRWWR6.js} +8 -6
  15. package/dist/{ConnectorSettings-ODC3LVHN.js.map → ConnectorSettings-MXFRWWR6.js.map} +1 -1
  16. package/dist/{DockLayout-TEOWEMSV.js → DockLayout-LM4AFMFY.js} +12 -11
  17. package/dist/{DockLayout-TEOWEMSV.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-CKQ5CVAC.js → ModelSettings-G7IFNC2Y.js} +8 -6
  21. package/dist/{ModelSettings-CKQ5CVAC.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-HSCPYUOC.js → SandboxSettings-NXAANMAX.js} +8 -6
  25. package/dist/{SandboxSettings-HSCPYUOC.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-MYWRFXRI.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-ECH6SHZ7.js → SkillSettings-FGGMSUNO.js} +8 -6
  35. package/dist/{SkillSettings-ECH6SHZ7.js.map → SkillSettings-FGGMSUNO.js.map} +1 -1
  36. package/dist/{TrueForgeUIWithRouter-KMHPOKLN.js → TrueForgeUIWithRouter-MZVJWJMB.js} +15 -11
  37. package/dist/{TrueForgeUIWithRouter-KMHPOKLN.js.map → TrueForgeUIWithRouter-MZVJWJMB.js.map} +1 -1
  38. package/dist/{WidgetLayout-4ZIG3RXV.js → WidgetLayout-6QM45OQQ.js} +19 -15
  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-FXCYLEFB.js → chunk-BSIPI3KV.js} +18 -2
  47. package/dist/chunk-BSIPI3KV.js.map +1 -0
  48. package/dist/{chunk-255AE5NI.js → chunk-CYHJDKFB.js} +118 -33
  49. package/dist/chunk-CYHJDKFB.js.map +1 -0
  50. package/dist/chunk-DJUFS2BW.js +27 -0
  51. package/dist/chunk-DJUFS2BW.js.map +1 -0
  52. package/dist/chunk-DMMZSZTN.js +252 -0
  53. package/dist/chunk-DMMZSZTN.js.map +1 -0
  54. package/dist/chunk-FJW36PD7.js +180 -0
  55. package/dist/chunk-FJW36PD7.js.map +1 -0
  56. package/dist/chunk-M62XY4NC.js +555 -0
  57. package/dist/chunk-M62XY4NC.js.map +1 -0
  58. package/dist/{chunk-JRRCAKEP.js → chunk-MPNSO7E6.js} +2 -2
  59. package/dist/{chunk-CFLVPV5M.js → chunk-QC42MLAK.js} +7 -2
  60. package/dist/chunk-QC42MLAK.js.map +1 -0
  61. package/dist/chunk-RDXBMTP5.js +32 -0
  62. package/dist/chunk-RDXBMTP5.js.map +1 -0
  63. package/dist/chunk-SFZNIO6U.js +18 -0
  64. package/dist/chunk-SFZNIO6U.js.map +1 -0
  65. package/dist/chunk-U7KURWW3.js +840 -0
  66. package/dist/chunk-U7KURWW3.js.map +1 -0
  67. package/dist/chunk-WVE3F724.js +200 -0
  68. package/dist/chunk-WVE3F724.js.map +1 -0
  69. package/dist/{chunk-IFLE7OMM.js → chunk-XAU7QFG3.js} +180 -38
  70. package/dist/chunk-XAU7QFG3.js.map +1 -0
  71. package/dist/chunk-Y6S4OVVQ.js +16 -0
  72. package/dist/chunk-Y6S4OVVQ.js.map +1 -0
  73. package/dist/chunk-ZKNUMH2M.js +119 -0
  74. package/dist/chunk-ZKNUMH2M.js.map +1 -0
  75. package/dist/chunk-ZTMKFZQ3.js +13214 -0
  76. package/dist/chunk-ZTMKFZQ3.js.map +1 -0
  77. package/dist/{createTrueFoundryServer-B72bU-J7.d.ts → createTrueFoundryServer-CmZnBh_l.d.ts} +15 -4
  78. package/dist/index.d.ts +1199 -161
  79. package/dist/index.js +699 -69
  80. package/dist/index.js.map +1 -1
  81. package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +552 -12
  82. package/dist/plugins/trueforge-agent-server-adapter/index.js +506 -188
  83. package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
  84. package/dist/styles.css +1 -1
  85. package/package.json +11 -10
  86. package/dist/DrawerLayout-2JOQ4EDZ.js +0 -159
  87. package/dist/DrawerLayout-2JOQ4EDZ.js.map +0 -1
  88. package/dist/OpenUiFenceBlock-3EFPY4JW.js +0 -9
  89. package/dist/SettingsBuilder-MYWRFXRI.js.map +0 -1
  90. package/dist/ShellRouteSync-T4WLY57Q.js.map +0 -1
  91. package/dist/SidebarLayout-6MHQYW45.js +0 -239
  92. package/dist/SidebarLayout-6MHQYW45.js.map +0 -1
  93. package/dist/WidgetLayout-4ZIG3RXV.js.map +0 -1
  94. package/dist/chunk-255AE5NI.js.map +0 -1
  95. package/dist/chunk-72LC2M3R.js +0 -567
  96. package/dist/chunk-72LC2M3R.js.map +0 -1
  97. package/dist/chunk-CFLVPV5M.js.map +0 -1
  98. package/dist/chunk-FXCYLEFB.js.map +0 -1
  99. package/dist/chunk-IFLE7OMM.js.map +0 -1
  100. package/dist/chunk-IWPDSPVA.js +0 -2068
  101. package/dist/chunk-IWPDSPVA.js.map +0 -1
  102. package/dist/chunk-OZTNBS6V.js +0 -75
  103. package/dist/chunk-OZTNBS6V.js.map +0 -1
  104. package/dist/chunk-PUFYHFND.js +0 -91
  105. package/dist/chunk-PUFYHFND.js.map +0 -1
  106. package/dist/chunk-WQULF5AT.js +0 -460
  107. package/dist/chunk-WQULF5AT.js.map +0 -1
  108. package/dist/chunk-XRTTKGKN.js +0 -6825
  109. package/dist/chunk-XRTTKGKN.js.map +0 -1
  110. package/dist/chunk-YIWUG6MC.js +0 -101
  111. package/dist/chunk-YIWUG6MC.js.map +0 -1
  112. /package/dist/{OpenUiFenceBlock-3EFPY4JW.js.map → AgentMetricChart-JPU3MFQ2.js.map} +0 -0
  113. /package/dist/{chunk-JRRCAKEP.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
  }
@@ -320,6 +245,9 @@ function createHarnessChatServer(options = {}) {
320
245
  const response = await client.sessions.get(sessionId);
321
246
  return toUiSession(response.data);
322
247
  },
248
+ async deleteSession({ sessionId }) {
249
+ await client.sessions.delete(sessionId);
250
+ },
323
251
  async updateSession({ sessionId, agentSpec }) {
324
252
  const response = await client.sessions.update(sessionId, {
325
253
  ...agentSpec === void 0 ? {} : { agent: { spec: toHarnessAgentSpec(agentSpec) } }
@@ -339,7 +267,7 @@ function createHarnessChatServer(options = {}) {
339
267
  for await (const item of stream.withMetadata()) {
340
268
  yield {
341
269
  sequenceNumber: sequenceNumber(item.id, fallbackSequence),
342
- event: { ...item.data }
270
+ event: toUiStreamingEvent(item.data)
343
271
  };
344
272
  fallbackSequence += 1;
345
273
  }
@@ -357,7 +285,7 @@ function createHarnessChatServer(options = {}) {
357
285
  for await (const item of stream.withMetadata()) {
358
286
  yield {
359
287
  sequenceNumber: sequenceNumber(item.id, fallbackSequence),
360
- event: { ...item.data }
288
+ event: toUiStreamingEvent(item.data)
361
289
  };
362
290
  fallbackSequence += 1;
363
291
  }
@@ -387,14 +315,256 @@ function createHarnessChatServer(options = {}) {
387
315
  };
388
316
  }
389
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
+
390
552
  // src/plugins/trueforge-agent-server-adapter/lists.ts
391
553
  async function listModels(client) {
392
554
  const body = await client.models.list();
393
555
  return body.data;
394
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
+ }
395
564
  async function listConfiguredMcpServers(client) {
396
- const body = await client.mcpServers.list();
397
- return body.data;
565
+ return drainListPages({
566
+ fetchPage: (pageToken) => listConfiguredMcpServersPage(client, { pageToken })
567
+ });
398
568
  }
399
569
  async function listSkills(client) {
400
570
  const body = await client.skills.list();
@@ -420,7 +590,7 @@ function toModelSelection({
420
590
  model,
421
591
  logo
422
592
  }) {
423
- const efforts = model.properties.reasoningEfforts;
593
+ const { contextLength, maxOutputTokens, reasoningEfforts } = model.properties;
424
594
  return {
425
595
  id: model.modelId,
426
596
  name: model.name,
@@ -429,7 +599,9 @@ function toModelSelection({
429
599
  ...logo === void 0 ? {} : { logo }
430
600
  },
431
601
  properties: {
432
- ...efforts !== void 0 && efforts.length > 0 ? { reasoningEfforts: [...efforts] } : {}
602
+ ...contextLength === void 0 ? {} : { contextLength },
603
+ ...maxOutputTokens === void 0 ? {} : { maxOutputTokens },
604
+ ...reasoningEfforts === void 0 ? {} : { reasoningEfforts: [...reasoningEfforts] }
433
605
  }
434
606
  };
435
607
  }
@@ -464,6 +636,19 @@ function createHarnessBuilderServer(options = {}) {
464
636
  return skills.map((skill) => ({ id: skill.name, name: skill.name, description: skill.description }));
465
637
  },
466
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
+ },
467
652
  async searchAgents(req) {
468
653
  const { data } = await client.agents.list();
469
654
  const query = req?.query?.trim().toLowerCase();
@@ -485,6 +670,12 @@ function createHarnessBuilderServer(options = {}) {
485
670
  }
486
671
  const created = await client.agents.create({ name: agentName, manifest });
487
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);
488
679
  }
489
680
  };
490
681
  }
@@ -814,6 +1005,126 @@ function createSkillCatalog(client) {
814
1005
  };
815
1006
  }
816
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
+
817
1128
  // src/plugins/trueforge-agent-server-adapter/index.ts
818
1129
  function createTrueForgeAgentUIServer(options = {}) {
819
1130
  const { catalog: catalogOverride, ...clientOptions } = options;
@@ -827,22 +1138,29 @@ function createTrueForgeAgentUIServer(options = {}) {
827
1138
  return createTrueFoundryServer({
828
1139
  chatServer: createHarnessChatServer({ client }),
829
1140
  ...createHarnessBuilderServer({ client }),
830
- catalog
1141
+ catalog,
1142
+ sessions: createHarnessAgentSessionsServer({ ...clientOptions, client }),
1143
+ metrics: createHarnessAgentMetricsServer({ ...clientOptions, client }),
1144
+ schedules: createScheduleServer({ client })
831
1145
  });
832
1146
  }
833
1147
  export {
834
1148
  configFromHarness,
835
1149
  createConnectorCatalog,
1150
+ createHarnessAgentMetricsServer,
1151
+ createHarnessAgentSessionsServer,
836
1152
  createHarnessBuilderServer,
837
1153
  createHarnessChatServer,
838
1154
  createModelProviderCatalog,
839
1155
  createSandboxProviderCatalog,
1156
+ createScheduleServer,
840
1157
  createSkillCatalog,
841
1158
  createTrueForgeAgentUIServer,
842
1159
  createTrueForgeClient,
843
1160
  filterUiSandboxProviders,
844
1161
  getCapabilities,
845
1162
  listConfiguredMcpServers,
1163
+ listConfiguredMcpServersPage,
846
1164
  listModels,
847
1165
  listSkills,
848
1166
  modelProviderLogosByName,