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

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 (115) hide show
  1. package/CHANGELOG.md +191 -0
  2. package/README.md +35 -12
  3. package/dist/AgentCodeSnippets-RJBB4DDE.js +89 -0
  4. package/dist/AgentCodeSnippets-RJBB4DDE.js.map +1 -0
  5. package/dist/AgentMetricChart-UPGSJ2WP.js +15 -0
  6. package/dist/AgentOverview-U5WIQXZN.js +169 -0
  7. package/dist/AgentOverview-U5WIQXZN.js.map +1 -0
  8. package/dist/AgentSessionEventTimeline-GRGIQTRE.js +88 -0
  9. package/dist/AgentSessionEventTimeline-GRGIQTRE.js.map +1 -0
  10. package/dist/AgentSessionEventTimelineChart-GNF4VOUT.js +591 -0
  11. package/dist/AgentSessionEventTimelineChart-GNF4VOUT.js.map +1 -0
  12. package/dist/AgentSessions-5OTF2BUW.js +323 -0
  13. package/dist/AgentSessions-5OTF2BUW.js.map +1 -0
  14. package/dist/{ConnectorSettings-FXQ5B7TN.js → ConnectorSettings-HDKGLDCY.js} +163 -125
  15. package/dist/ConnectorSettings-HDKGLDCY.js.map +1 -0
  16. package/dist/{DockLayout-LBNQJZNF.js → DockLayout-D2FPQCAL.js} +11 -10
  17. package/dist/{DockLayout-LBNQJZNF.js.map → DockLayout-D2FPQCAL.js.map} +1 -1
  18. package/dist/DrawerLayout-HUV7RAWL.js +186 -0
  19. package/dist/DrawerLayout-HUV7RAWL.js.map +1 -0
  20. package/dist/{ModelSettings-4L4LOQJA.js → ModelSettings-VNQ7HPKH.js} +23 -27
  21. package/dist/ModelSettings-VNQ7HPKH.js.map +1 -0
  22. package/dist/OpenUiFenceBlock-KPZFLUSC.js +9 -0
  23. package/dist/OpenUiFenceBlock-KPZFLUSC.js.map +1 -0
  24. package/dist/{SandboxSettings-Z4ZG6ZX4.js → SandboxSettings-ZLXGMFBF.js} +18 -20
  25. package/dist/SandboxSettings-ZLXGMFBF.js.map +1 -0
  26. package/dist/SchedulesPage-QKYI2Z3A.js +15 -0
  27. package/dist/SchedulesPage-QKYI2Z3A.js.map +1 -0
  28. package/dist/{SettingsBuilder-WF7ZWKQW.js → SettingsBuilder-RVVYXOJW.js} +27 -23
  29. package/dist/SettingsBuilder-RVVYXOJW.js.map +1 -0
  30. package/dist/ShellRouteSync-SJXFKUAJ.js +390 -0
  31. package/dist/ShellRouteSync-SJXFKUAJ.js.map +1 -0
  32. package/dist/SidebarLayout-KYA76FQ7.js +330 -0
  33. package/dist/SidebarLayout-KYA76FQ7.js.map +1 -0
  34. package/dist/{SkillSettings-3EPPC3IT.js → SkillSettings-7OHT7FPI.js} +25 -21
  35. package/dist/SkillSettings-7OHT7FPI.js.map +1 -0
  36. package/dist/{TrueForgeUIWithRouter-NZ4FGPE4.js → TrueForgeUIWithRouter-LKG4XLW6.js} +14 -10
  37. package/dist/{TrueForgeUIWithRouter-NZ4FGPE4.js.map → TrueForgeUIWithRouter-LKG4XLW6.js.map} +1 -1
  38. package/dist/{WidgetLayout-3QZ357FL.js → WidgetLayout-W2RGGOQ3.js} +17 -13
  39. package/dist/WidgetLayout-W2RGGOQ3.js.map +1 -0
  40. package/dist/chunk-2GIZY3JJ.js +1062 -0
  41. package/dist/chunk-2GIZY3JJ.js.map +1 -0
  42. package/dist/chunk-2QTH6JHX.js +217 -0
  43. package/dist/chunk-2QTH6JHX.js.map +1 -0
  44. package/dist/{chunk-FJ5RSSMA.js → chunk-3ZW74FHC.js} +118 -164
  45. package/dist/chunk-3ZW74FHC.js.map +1 -0
  46. package/dist/chunk-67ZO7Z2W.js +184 -0
  47. package/dist/chunk-67ZO7Z2W.js.map +1 -0
  48. package/dist/{chunk-CFLVPV5M.js → chunk-7AAO4UDQ.js} +8 -2
  49. package/dist/chunk-7AAO4UDQ.js.map +1 -0
  50. package/dist/{chunk-B52K63AW.js → chunk-CG75X77Q.js} +2 -2
  51. package/dist/chunk-DJUFS2BW.js +27 -0
  52. package/dist/chunk-DJUFS2BW.js.map +1 -0
  53. package/dist/chunk-DPPOEFBD.js +517 -0
  54. package/dist/chunk-DPPOEFBD.js.map +1 -0
  55. package/dist/chunk-EPAL2HD5.js +1629 -0
  56. package/dist/chunk-EPAL2HD5.js.map +1 -0
  57. package/dist/chunk-GG23N2GW.js +15018 -0
  58. package/dist/chunk-GG23N2GW.js.map +1 -0
  59. package/dist/chunk-JCL3Q7RW.js +587 -0
  60. package/dist/chunk-JCL3Q7RW.js.map +1 -0
  61. package/dist/chunk-JKEBMGLH.js +682 -0
  62. package/dist/chunk-JKEBMGLH.js.map +1 -0
  63. package/dist/chunk-KSGNKS2D.js +296 -0
  64. package/dist/chunk-KSGNKS2D.js.map +1 -0
  65. package/dist/{chunk-WREC7D54.js → chunk-PCI6VMB5.js} +268 -48
  66. package/dist/chunk-PCI6VMB5.js.map +1 -0
  67. package/dist/chunk-PQ7VWBQQ.js +121 -0
  68. package/dist/chunk-PQ7VWBQQ.js.map +1 -0
  69. package/dist/chunk-RDXBMTP5.js +32 -0
  70. package/dist/chunk-RDXBMTP5.js.map +1 -0
  71. package/dist/chunk-T6QQV5LK.js +238 -0
  72. package/dist/chunk-T6QQV5LK.js.map +1 -0
  73. package/dist/chunk-Y6S4OVVQ.js +16 -0
  74. package/dist/chunk-Y6S4OVVQ.js.map +1 -0
  75. package/dist/{createTrueFoundryServer-B72bU-J7.d.ts → createTrueFoundryServer-B_FYhSdn.d.ts} +18 -4
  76. package/dist/index.d.ts +1287 -46
  77. package/dist/index.js +266 -63
  78. package/dist/index.js.map +1 -1
  79. package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +590 -11
  80. package/dist/plugins/trueforge-agent-server-adapter/index.js +607 -204
  81. package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
  82. package/dist/styles.css +1 -1
  83. package/package.json +10 -8
  84. package/dist/ConnectorSettings-FXQ5B7TN.js.map +0 -1
  85. package/dist/DrawerLayout-Q6UK4VMI.js +0 -159
  86. package/dist/DrawerLayout-Q6UK4VMI.js.map +0 -1
  87. package/dist/ModelSettings-4L4LOQJA.js.map +0 -1
  88. package/dist/OpenUiFenceBlock-6UIIAVBX.js +0 -9
  89. package/dist/SandboxSettings-Z4ZG6ZX4.js.map +0 -1
  90. package/dist/SettingsBuilder-WF7ZWKQW.js.map +0 -1
  91. package/dist/ShellRouteSync-T4WLY57Q.js +0 -172
  92. package/dist/ShellRouteSync-T4WLY57Q.js.map +0 -1
  93. package/dist/SidebarLayout-3WZ3CVON.js +0 -256
  94. package/dist/SidebarLayout-3WZ3CVON.js.map +0 -1
  95. package/dist/SkillSettings-3EPPC3IT.js.map +0 -1
  96. package/dist/WidgetLayout-3QZ357FL.js.map +0 -1
  97. package/dist/chunk-36KOSC2J.js +0 -567
  98. package/dist/chunk-36KOSC2J.js.map +0 -1
  99. package/dist/chunk-3S6KHO7H.js +0 -2121
  100. package/dist/chunk-3S6KHO7H.js.map +0 -1
  101. package/dist/chunk-7L63OK3O.js +0 -91
  102. package/dist/chunk-7L63OK3O.js.map +0 -1
  103. package/dist/chunk-CFLVPV5M.js.map +0 -1
  104. package/dist/chunk-FJ5RSSMA.js.map +0 -1
  105. package/dist/chunk-OSV3HI5M.js +0 -6891
  106. package/dist/chunk-OSV3HI5M.js.map +0 -1
  107. package/dist/chunk-WQULF5AT.js +0 -460
  108. package/dist/chunk-WQULF5AT.js.map +0 -1
  109. package/dist/chunk-WREC7D54.js.map +0 -1
  110. package/dist/chunk-YIWUG6MC.js +0 -101
  111. package/dist/chunk-YIWUG6MC.js.map +0 -1
  112. package/dist/chunk-ZXOADNF3.js +0 -75
  113. package/dist/chunk-ZXOADNF3.js.map +0 -1
  114. /package/dist/{OpenUiFenceBlock-6UIIAVBX.js.map → AgentMetricChart-UPGSJ2WP.js.map} +0 -0
  115. /package/dist/{chunk-B52K63AW.js.map → chunk-CG75X77Q.js.map} +0 -0
@@ -1,195 +1,111 @@
1
1
  import {
2
2
  createTrueFoundryServer
3
- } from "../../chunk-CFLVPV5M.js";
3
+ } from "../../chunk-7AAO4UDQ.js";
4
+ import {
5
+ readSessionIsCreateAgent
6
+ } from "../../chunk-RDXBMTP5.js";
4
7
 
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" };
8
+ // src/plugins/trueforge-agent-server-adapter/client.ts
9
+ import { TrueForge } from "@truefoundry/trueforge-sdk";
10
+ var DEFAULT_BASE_URL = "/";
11
+ function resolveTrueForgeBaseUrl(baseUrl) {
12
+ if (/^https?:\/\//i.test(baseUrl)) return baseUrl;
13
+ const origin = globalThis.location?.origin;
14
+ if (typeof origin === "string" && origin.length > 0 && origin !== "null") {
15
+ return new URL(baseUrl, origin).href;
13
16
  }
14
- const headerName = Object.keys(auth.headers)[0];
15
- return {
16
- type: "header",
17
- ...headerName === void 0 ? {} : { headerName }
18
- };
17
+ return baseUrl;
19
18
  }
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
- description: server.description,
41
- ...server.logo === void 0 ? {} : { logo: server.logo },
42
- auth: toUiAuthPublic(server.auth)
43
- };
44
- }
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
- };
19
+ function createTrueForgeClient(options = {}) {
20
+ return new TrueForge({
21
+ baseUrl: resolveTrueForgeBaseUrl(options.baseUrl ?? DEFAULT_BASE_URL),
22
+ ...options.token === void 0 ? {} : { token: options.token },
23
+ ...options.fetch === void 0 ? {} : { fetch: options.fetch }
24
+ });
84
25
  }
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;
26
+ function parseIsoDate(value) {
27
+ const date = new Date(value);
28
+ if (Number.isNaN(date.getTime())) {
29
+ throw new Error(`Invalid ISO timestamp: ${value}`);
93
30
  }
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 };
31
+ return date;
32
+ }
33
+
34
+ // src/plugins/trueforge-agent-server-adapter/agentMetricsServer.ts
35
+ function toHarnessChartName(name) {
36
+ if (name === "sessions_over_time" || name === "sessions_cost_over_time" || name === "turns_over_time") {
37
+ return name;
117
38
  }
39
+ throw new Error(`Unsupported Harness metrics chart: ${name}`);
40
+ }
41
+ function createHarnessAgentMetricsServer(options = {}) {
42
+ const client = options.client ?? createTrueForgeClient(options);
118
43
  return {
119
- getConnectorCatalog: async () => {
120
- const body = await client.catalogs.mcpServers.list();
121
- return body.data.map(toUiCatalogEntry);
44
+ async getCharts() {
45
+ const { data } = await client.internal.metrics.listCharts();
46
+ return data.charts;
122
47
  },
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
- })
48
+ async getMeters({ agentId, startTimestamp, endTimestamp }) {
49
+ const { data } = await client.internal.metrics.getMeters({
50
+ agentId,
51
+ startTimestamp: parseIsoDate(startTimestamp),
52
+ endTimestamp: parseIsoDate(endTimestamp)
151
53
  });
152
- return toUiConnector(body.data);
54
+ return data.meters;
153
55
  },
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
- })
56
+ async getChartData({ agentId, startTimestamp, endTimestamp, chartName }) {
57
+ const { data } = await client.internal.metrics.getChartData({
58
+ agentId,
59
+ startTimestamp: parseIsoDate(startTimestamp),
60
+ endTimestamp: parseIsoDate(endTimestamp),
61
+ chartName: toHarnessChartName(chartName)
163
62
  });
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);
63
+ return data;
180
64
  }
181
65
  };
182
66
  }
183
67
 
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
- });
68
+ // src/plugins/trueforge-agent-server-adapter/toUiTurnState.ts
69
+ function toUiTurnDoneMetrics(metrics) {
70
+ return {
71
+ totalInputTokens: metrics.totalInputTokens ?? 0,
72
+ totalOutputTokens: metrics.totalOutputTokens ?? 0,
73
+ totalTokens: metrics.totalTokens ?? 0,
74
+ totalCacheReadTokens: metrics.totalCacheReadTokens ?? 0,
75
+ totalCacheWriteTokens: metrics.totalCacheWriteTokens ?? 0,
76
+ totalReasoningTokens: metrics.totalReasoningTokens ?? 0,
77
+ ...metrics.totalCostInUsd == null ? {} : { totalCostInUsd: metrics.totalCostInUsd }
78
+ };
79
+ }
80
+ function toUiTurnState(state) {
81
+ return state.status === "running" ? { status: "running" } : toUiTerminalTurnState(state);
82
+ }
83
+ function toUiTerminalTurnState(state) {
84
+ switch (state.status) {
85
+ case "cancelled":
86
+ return { status: "cancelled", reason: state.reason, completedAt: state.completedAt };
87
+ case "error":
88
+ return { status: "error", message: state.message, completedAt: state.completedAt };
89
+ case "done":
90
+ return {
91
+ status: "done",
92
+ completedAt: state.completedAt,
93
+ requiredActions: state.requiredActions,
94
+ ...state.output == null ? {} : { output: state.output },
95
+ ...state.metrics == null ? {} : { metrics: toUiTurnDoneMetrics(state.metrics) }
96
+ };
97
+ }
98
+ }
99
+ function toUiSessionEvent(event) {
100
+ if (event.type !== "turn.done") return { ...event };
101
+ return { ...event, state: toUiTerminalTurnState(event.state) };
102
+ }
103
+ function toUiStreamingEvent(event) {
104
+ if (event.type !== "turn.done") return { ...event };
105
+ return { ...event, state: toUiTerminalTurnState(event.state) };
106
+ }
107
+ function toUiEventItem(item) {
108
+ return { turnId: item.turnId, event: toUiSessionEvent(item.event) };
193
109
  }
194
110
 
195
111
  // src/plugins/trueforge-agent-server-adapter/chatServer.ts
@@ -197,7 +113,10 @@ function toUiMcpServer(server) {
197
113
  return server;
198
114
  }
199
115
  function toUiSkill(skill) {
200
- return { name: skill.name };
116
+ return { name: skill.name, preload: skill.preload === true };
117
+ }
118
+ function toHarnessSkill(skill) {
119
+ return { name: skill.id ?? skill.name, preload: skill.preload === true };
201
120
  }
202
121
  function toHarnessAgentSpec(spec) {
203
122
  const { skills, mcpServers, ...rest } = spec;
@@ -213,7 +132,7 @@ function toHarnessAgentSpec(spec) {
213
132
  return server;
214
133
  })
215
134
  },
216
- ...skills === void 0 ? {} : { skills: skills.map(({ name }) => ({ name })) }
135
+ ...skills === void 0 ? {} : { skills: skills.map(toHarnessSkill) }
217
136
  };
218
137
  }
219
138
  function toUiAgentSpec(spec) {
@@ -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
  }
@@ -312,7 +237,8 @@ function createHarnessChatServer(options = {}) {
312
237
  ...request.limit === void 0 ? {} : { limit: request.limit },
313
238
  ...request.order === void 0 ? {} : { order: request.order },
314
239
  ...request.pageToken === void 0 ? {} : { pageToken: request.pageToken },
315
- ...request.agentId === void 0 || request.agentId.length === 0 ? {} : { agentId: request.agentId }
240
+ ...request.agentId === void 0 || request.agentId.length === 0 ? {} : { agentId: request.agentId },
241
+ ...request.createdByMe === void 0 ? {} : { createdByMe: request.createdByMe }
316
242
  });
317
243
  return toListResult(page, toUiSession);
318
244
  },
@@ -342,7 +268,7 @@ function createHarnessChatServer(options = {}) {
342
268
  for await (const item of stream.withMetadata()) {
343
269
  yield {
344
270
  sequenceNumber: sequenceNumber(item.id, fallbackSequence),
345
- event: { ...item.data }
271
+ event: toUiStreamingEvent(item.data)
346
272
  };
347
273
  fallbackSequence += 1;
348
274
  }
@@ -360,7 +286,7 @@ function createHarnessChatServer(options = {}) {
360
286
  for await (const item of stream.withMetadata()) {
361
287
  yield {
362
288
  sequenceNumber: sequenceNumber(item.id, fallbackSequence),
363
- event: { ...item.data }
289
+ event: toUiStreamingEvent(item.data)
364
290
  };
365
291
  fallbackSequence += 1;
366
292
  }
@@ -390,6 +316,295 @@ function createHarnessChatServer(options = {}) {
390
316
  };
391
317
  }
392
318
 
319
+ // src/plugins/trueforge-agent-server-adapter/agentSessionsServer.ts
320
+ function toSessionListEntry(session) {
321
+ return {
322
+ id: session.id,
323
+ createdAt: session.createdAt,
324
+ updatedAt: session.updatedAt,
325
+ lastActivityAt: session.updatedAt,
326
+ isCreateAgent: readSessionIsCreateAgent(session.metadata),
327
+ isMutable: session.agent.type === "inline",
328
+ metrics: {
329
+ totalTurns: session.metrics.totalTurns,
330
+ ...session.metrics.totalCostInUsd == null ? {} : { totalCostInUsd: session.metrics.totalCostInUsd },
331
+ totalDurationMs: session.metrics.totalDurationMs
332
+ },
333
+ ...session.title === null ? {} : { title: session.title },
334
+ ...session.agent.type === "reference" && session.agent.name !== null ? { agentName: session.agent.name } : {},
335
+ ...session.agent.type === "inline" ? { agentSpec: toUiAgentSpec(session.agent.spec) } : {},
336
+ ...session.source?.type === "schedule" ? { sourceType: session.source.type } : {}
337
+ };
338
+ }
339
+ function createHarnessAgentSessionsServer(options = {}) {
340
+ const client = options.client ?? createTrueForgeClient(options);
341
+ return {
342
+ async getAgent({ agentId }) {
343
+ const { data } = await client.agents.get(agentId);
344
+ return {
345
+ agentId: data.id,
346
+ name: data.name,
347
+ description: data.description,
348
+ agentSpec: toUiAgentSpec(data.manifest)
349
+ };
350
+ },
351
+ async getCodeSnippets({ agentId }) {
352
+ const absoluteBaseUrl = resolveTrueForgeBaseUrl(options.baseUrl ?? "/").replace(/\/$/, "");
353
+ const { data } = await client.internal.agents.getCodeSnippets(
354
+ agentId,
355
+ /^https?:\/\//i.test(absoluteBaseUrl) ? { baseUrl: absoluteBaseUrl } : void 0
356
+ );
357
+ return data.snippets;
358
+ },
359
+ async listSessions(requestParams = {}) {
360
+ const page = await client.sessions.list({
361
+ ...requestParams.limit === void 0 ? {} : { limit: requestParams.limit },
362
+ ...requestParams.order === void 0 ? {} : { order: requestParams.order },
363
+ ...requestParams.pageToken === void 0 ? {} : { pageToken: requestParams.pageToken },
364
+ ...requestParams.startTimestamp === void 0 ? {} : { startTimestamp: parseIsoDate(requestParams.startTimestamp) },
365
+ ...requestParams.endTimestamp === void 0 ? {} : { endTimestamp: parseIsoDate(requestParams.endTimestamp) },
366
+ ...requestParams.agentId === void 0 || requestParams.agentId.length === 0 ? {} : { agentId: requestParams.agentId },
367
+ ...requestParams.createdByMe === void 0 ? {} : { createdByMe: requestParams.createdByMe }
368
+ });
369
+ return toListResult(page, toSessionListEntry);
370
+ },
371
+ async listSessionEvents({ sessionId, pageToken, limit }) {
372
+ const page = await client.sessions.listEvents(sessionId, {
373
+ ...pageToken === void 0 ? {} : { pageToken },
374
+ ...limit === void 0 ? {} : { limit }
375
+ });
376
+ return toListResult(page, toUiEventItem);
377
+ }
378
+ };
379
+ }
380
+
381
+ // src/plugins/trueforge-agent-server-adapter/agentsList.ts
382
+ var AGENTS_PAGE_DEFAULT = 50;
383
+ var AGENTS_PAGE_LIMIT = 100;
384
+ function clampAgentsPageSize(size) {
385
+ return Math.min(Math.max(size, 1), AGENTS_PAGE_LIMIT);
386
+ }
387
+ async function listAgentsPage({
388
+ client,
389
+ limit,
390
+ offset = 0,
391
+ agentName
392
+ }) {
393
+ const pageSize = clampAgentsPageSize(limit);
394
+ const start = Math.max(0, offset);
395
+ const page = await client.agents.list({
396
+ limit: pageSize,
397
+ ...agentName === void 0 ? {} : { agentName }
398
+ });
399
+ let at = 0;
400
+ while (at < start) {
401
+ if (!page.hasNextPage()) return [];
402
+ await page.getNextPage();
403
+ at += pageSize;
404
+ }
405
+ return [...page.data];
406
+ }
407
+ async function drainAgentsList(client) {
408
+ const items = [];
409
+ const page = await client.agents.list({ limit: AGENTS_PAGE_DEFAULT });
410
+ for (; ; ) {
411
+ items.push(...page.data);
412
+ if (!page.hasNextPage()) break;
413
+ await page.getNextPage();
414
+ }
415
+ return items;
416
+ }
417
+
418
+ // src/plugins/trueforge-agent-server-adapter/catalogs/connectorCatalog.ts
419
+ var DEFAULT_API_KEY_HEADER = "Authorization";
420
+ function toUiAuthPublic(auth) {
421
+ if (auth === void 0) {
422
+ return { type: "none" };
423
+ }
424
+ if (auth.type === "dcr") {
425
+ return { type: "dcr" };
426
+ }
427
+ const headerName = Object.keys(auth.headers)[0];
428
+ return {
429
+ type: "header",
430
+ ...headerName === void 0 ? {} : { headerName }
431
+ };
432
+ }
433
+ function toHarnessAuth(auth) {
434
+ if (auth.type === "none") {
435
+ return void 0;
436
+ }
437
+ if (auth.type === "dcr") {
438
+ return { type: "dcr" };
439
+ }
440
+ const apiKey = auth.apiKey?.trim();
441
+ if (apiKey === void 0 || apiKey === "") {
442
+ throw new Error("API key is required for header-authenticated MCP servers");
443
+ }
444
+ const trimmedHeader = auth.headerName?.trim();
445
+ const headerName = trimmedHeader !== void 0 && trimmedHeader !== "" ? trimmedHeader : DEFAULT_API_KEY_HEADER;
446
+ return { type: "header", headers: { [headerName]: apiKey } };
447
+ }
448
+ function toUiCatalogEntry(server) {
449
+ return {
450
+ id: server.name,
451
+ name: server.name,
452
+ url: server.url,
453
+ description: server.description,
454
+ ...server.logo === void 0 ? {} : { logo: server.logo },
455
+ auth: toUiAuthPublic(server.auth)
456
+ };
457
+ }
458
+ function toUiToolAnnotations(value) {
459
+ if (typeof value !== "object" || value === null) return void 0;
460
+ const readOnlyHint = Reflect.get(value, "readOnlyHint");
461
+ const destructiveHint = Reflect.get(value, "destructiveHint");
462
+ const annotations = {
463
+ ...typeof readOnlyHint === "boolean" ? { readOnlyHint } : {},
464
+ ...typeof destructiveHint === "boolean" ? { destructiveHint } : {}
465
+ };
466
+ return Object.keys(annotations).length > 0 ? annotations : void 0;
467
+ }
468
+ function toUiTool(tool) {
469
+ const name = typeof tool.name === "string" && tool.name !== "" ? tool.name : "tool";
470
+ const description = typeof tool.description === "string" ? tool.description : "";
471
+ const annotations = toUiToolAnnotations(Reflect.get(tool, "annotations"));
472
+ return annotations === void 0 ? { id: name, name, description } : { id: name, name, description, annotations };
473
+ }
474
+ function toUiConnector(server) {
475
+ const auth = toUiAuthPublic(server.manifest.auth);
476
+ return {
477
+ id: server.name,
478
+ name: server.name,
479
+ description: server.manifest.description,
480
+ url: server.manifest.url,
481
+ auth,
482
+ requiresAuth: server.authStatus.status === "auth_required",
483
+ authenticated: server.authStatus.status !== "auth_required"
484
+ };
485
+ }
486
+ function toUiConnectorFromReadEntry(server) {
487
+ const auth = server.auth?.type ? { type: server.auth.type } : { type: "none" };
488
+ return {
489
+ id: server.name,
490
+ name: server.name,
491
+ description: server.url,
492
+ url: server.url,
493
+ auth,
494
+ requiresAuth: server.authStatus.status === "auth_required",
495
+ authenticated: server.authStatus.status !== "auth_required"
496
+ };
497
+ }
498
+ function toHarnessManifest(req) {
499
+ const auth = toHarnessAuth(req.auth);
500
+ const trimmed = req.description?.trim();
501
+ return {
502
+ type: "remote",
503
+ name: req.name,
504
+ url: req.url,
505
+ description: trimmed !== void 0 && trimmed !== "" ? trimmed : `${req.name} MCP server`,
506
+ ...auth === void 0 ? {} : { auth }
507
+ };
508
+ }
509
+ function createConnectorCatalog(client) {
510
+ async function getConfigured(name) {
511
+ const listed = await client.settings.mcpServers.list();
512
+ const existing = listed.data.find((server) => server.name === name);
513
+ if (existing === void 0) {
514
+ throw new Error(`MCP server "${name}" not found`);
515
+ }
516
+ return existing;
517
+ }
518
+ async function resolveWriteAuth(req) {
519
+ if (req.auth.type !== "header") {
520
+ return req.auth;
521
+ }
522
+ const apiKey = req.auth.apiKey?.trim();
523
+ if (apiKey !== void 0 && apiKey !== "") {
524
+ return req.auth;
525
+ }
526
+ if (req.id === void 0) {
527
+ throw new Error("API key is required for header-authenticated MCP servers");
528
+ }
529
+ const existing = await getConfigured(req.id);
530
+ if (existing.manifest.auth?.type !== "header") {
531
+ throw new Error(`MCP server "${req.id}" has no stored header credentials to reuse`);
532
+ }
533
+ const preferredHeader = req.auth.headerName?.trim();
534
+ const storedHeaderName = Object.keys(existing.manifest.auth.headers)[0];
535
+ const headerName = preferredHeader !== void 0 && preferredHeader !== "" ? preferredHeader : storedHeaderName ?? DEFAULT_API_KEY_HEADER;
536
+ const stored = existing.manifest.auth.headers[headerName] ?? Object.values(existing.manifest.auth.headers)[0];
537
+ if (stored === void 0) {
538
+ throw new Error(`MCP server "${req.id}" has no stored header credentials to reuse`);
539
+ }
540
+ return { type: "header", apiKey: stored, headerName };
541
+ }
542
+ return {
543
+ getConnectorCatalog: async () => {
544
+ const body = await client.catalogs.mcpServers.list();
545
+ return body.data.map(toUiCatalogEntry);
546
+ },
547
+ getConnector: async (req) => {
548
+ const body = await client.settings.mcpServers.get(req.id);
549
+ return toUiConnector(body.data);
550
+ },
551
+ listConnectors: async (req) => {
552
+ const body = await client.settings.mcpServers.list();
553
+ const connectors = body.data.map(toUiConnector);
554
+ const query = req?.query?.trim().toLowerCase();
555
+ if (query === void 0 || query === "") {
556
+ return connectors;
557
+ }
558
+ return connectors.filter(
559
+ (connector) => connector.name.toLowerCase().includes(query) || connector.description.toLowerCase().includes(query) || connector.url.toLowerCase().includes(query)
560
+ );
561
+ },
562
+ getToolsByConnectorId: async ({ id }) => {
563
+ const body = await client.mcpServers.listTools(id);
564
+ return body.data.map(toUiTool);
565
+ },
566
+ createConnector: async (req) => {
567
+ const auth = await resolveWriteAuth({ auth: req.auth });
568
+ const body = await client.settings.mcpServers.create({
569
+ manifest: toHarnessManifest({
570
+ name: req.name,
571
+ url: req.url,
572
+ auth,
573
+ description: req.description
574
+ })
575
+ });
576
+ return toUiConnector(body.data);
577
+ },
578
+ updateConnector: async (req) => {
579
+ const auth = await resolveWriteAuth({ id: req.id, auth: req.auth });
580
+ const body = await client.settings.mcpServers.createOrUpdate({
581
+ manifest: toHarnessManifest({
582
+ name: req.id,
583
+ url: req.url,
584
+ auth,
585
+ description: req.description
586
+ })
587
+ });
588
+ return toUiConnector(body.data);
589
+ },
590
+ authenticateConnector: async (req) => {
591
+ const result = await client.mcpServers.authorize(
592
+ req.id,
593
+ req.returnTo === void 0 ? {} : { returnTo: req.returnTo }
594
+ );
595
+ return { status: result.status, authorization_endpoint: result.authorizationUrl };
596
+ },
597
+ disconnectConnector: async (req) => {
598
+ const existing = await getConfigured(req.id);
599
+ if (existing.manifest.auth?.type !== "dcr") {
600
+ throw new Error(`Disconnect is only supported for OAuth MCP servers`);
601
+ }
602
+ const body = await client.mcpServers.deleteAuthorization(req.id);
603
+ return toUiConnector(body.data);
604
+ }
605
+ };
606
+ }
607
+
393
608
  // src/plugins/trueforge-agent-server-adapter/lists.ts
394
609
  async function listModels(client) {
395
610
  const body = await client.models.list();
@@ -423,7 +638,7 @@ function toModelSelection({
423
638
  model,
424
639
  logo
425
640
  }) {
426
- const efforts = model.properties.reasoningEfforts;
641
+ const { contextLength, maxOutputTokens, reasoningEfforts } = model.properties;
427
642
  return {
428
643
  id: model.modelId,
429
644
  name: model.name,
@@ -432,7 +647,9 @@ function toModelSelection({
432
647
  ...logo === void 0 ? {} : { logo }
433
648
  },
434
649
  properties: {
435
- ...efforts !== void 0 && efforts.length > 0 ? { reasoningEfforts: [...efforts] } : {}
650
+ ...contextLength === void 0 ? {} : { contextLength },
651
+ ...maxOutputTokens === void 0 ? {} : { maxOutputTokens },
652
+ ...reasoningEfforts === void 0 ? {} : { reasoningEfforts: [...reasoningEfforts] }
436
653
  }
437
654
  };
438
655
  }
@@ -440,7 +657,9 @@ function toLibraryEntry(agent) {
440
657
  return {
441
658
  name: agent.name,
442
659
  agentId: agent.id,
443
- agentSpec: toUiAgentSpec(agent.manifest)
660
+ description: agent.description,
661
+ agentSpec: toUiAgentSpec(agent.manifest),
662
+ createdBySubject: agent.createdBySubject
444
663
  };
445
664
  }
446
665
  function createHarnessBuilderServer(options = {}) {
@@ -462,32 +681,77 @@ function createHarnessBuilderServer(options = {}) {
462
681
  });
463
682
  },
464
683
  // Skills require a configured sandbox provider; keep the picker empty when skill capability is off.
684
+ // Catalog AvailableSkill.name is store identity (FQN in TFY). Picker `id` copies that
685
+ // attach key; `name` is displayName so the draft can show a label without losing the wire key.
686
+ // Draft mounts `{ id, name }`; toHarnessSkill admits AgentSpec.skills[].name = id ?? name.
465
687
  getSkills: async () => {
466
688
  const skills = await listSkills(client);
467
- return skills.map((skill) => ({ id: skill.name, name: skill.name, description: skill.description }));
689
+ return skills.map((skill) => {
690
+ const { display_name, repository_name, version: versionRaw } = skill.metadata ?? {};
691
+ const version = Number(versionRaw);
692
+ const hasVersion = Number.isInteger(version) && version > 0;
693
+ return {
694
+ id: skill.name,
695
+ name: display_name ?? skill.name,
696
+ description: skill.description,
697
+ ...repository_name === void 0 ? {} : { skillRepoName: repository_name },
698
+ ...hasVersion ? {
699
+ version,
700
+ loadVersions: async () => (await client.skills.listVersions({ name: skill.name })).data
701
+ } : {}
702
+ };
703
+ });
468
704
  },
469
705
  getMcp: async () => (await listConfiguredMcpServers(client)).map(toUiConnectorFromReadEntry),
706
+ getMcpConnector: async ({ connectorId }) => {
707
+ const body = await client.mcpServers.get(connectorId);
708
+ return toUiConnectorFromReadEntry(body.data);
709
+ },
710
+ getMcpTools: async ({ connectorId }) => {
711
+ const body = await client.mcpServers.listTools(connectorId);
712
+ return body.data.flatMap(
713
+ (tool) => typeof tool.name === "string" && tool.name.trim() !== "" ? [toUiTool(tool)] : []
714
+ );
715
+ },
470
716
  async searchAgents(req) {
471
- const { data } = await client.agents.list();
472
- const query = req?.query?.trim().toLowerCase();
473
- const filtered = query === void 0 || query === "" ? data : data.filter((agent) => agent.name.toLowerCase().includes(query));
717
+ const limit = clampAgentsPageSize(req?.limit ?? AGENTS_PAGE_DEFAULT);
474
718
  const offset = req?.offset ?? 0;
475
- const limit = req?.limit ?? 50;
476
- return filtered.slice(offset, offset + limit).map(toLibraryEntry);
719
+ const query = req?.query?.trim();
720
+ const rows = await listAgentsPage({
721
+ client,
722
+ limit,
723
+ offset,
724
+ ...query === void 0 || query === "" ? {} : { agentName: query }
725
+ });
726
+ return rows.map(toLibraryEntry);
477
727
  },
478
- async saveAgent({ agentName, agentSpec, intent }) {
728
+ async saveAgent({ agentName, description: descriptionRaw, agentSpec, intent }) {
479
729
  const manifest = toHarnessAgentSpec(agentSpec);
730
+ const description = descriptionRaw?.trim();
480
731
  if (intent === "update") {
481
- const { data } = await client.agents.list();
482
- const existing = data.find((agent) => agent.name === agentName);
732
+ const agents = await drainAgentsList(client);
733
+ const existing = agents.find((agent) => agent.name === agentName);
483
734
  if (!existing) {
484
735
  return {};
485
736
  }
486
- await client.agents.update(existing.id, { manifest });
737
+ await client.agents.update(existing.id, {
738
+ ...description ? { description } : {},
739
+ manifest
740
+ });
487
741
  return { agentId: existing.id };
488
742
  }
489
- const created = await client.agents.create({ name: agentName, manifest });
743
+ const created = await client.agents.create({
744
+ name: agentName,
745
+ description: description || agentName,
746
+ manifest
747
+ });
490
748
  return { agentId: created.data.id };
749
+ },
750
+ async deleteAgent({ agentName }) {
751
+ const agents = await drainAgentsList(client);
752
+ const existing = agents.find((agent) => agent.name === agentName);
753
+ if (!existing) return;
754
+ await client.agents.delete(existing.id);
491
755
  }
492
756
  };
493
757
  }
@@ -769,10 +1033,12 @@ function toHarnessManifest3(req) {
769
1033
  };
770
1034
  }
771
1035
  function toUiSkill2(skill, catalogNames) {
1036
+ const manifest = skill.manifest;
1037
+ const displayName = "displayName" in manifest && typeof manifest.displayName === "string" ? manifest.displayName : manifest.name;
772
1038
  const base = {
773
1039
  id: skill.name,
774
- name: skill.name,
775
- description: skill.manifest.description
1040
+ name: displayName,
1041
+ description: manifest.description
776
1042
  };
777
1043
  if (catalogNames.has(skill.name)) {
778
1044
  return { ...base, catalogId: skill.name };
@@ -817,9 +1083,138 @@ function createSkillCatalog(client) {
817
1083
  };
818
1084
  }
819
1085
 
1086
+ // src/plugins/trueforge-agent-server-adapter/permissionsServer.ts
1087
+ function createHarnessPermissionsServer(options = {}) {
1088
+ const client = options.client ?? createTrueForgeClient(options);
1089
+ return {
1090
+ listPermissions: async (request) => client.internal.listPermissions(request)
1091
+ };
1092
+ }
1093
+
1094
+ // src/plugins/trueforge-agent-server-adapter/schedules/scheduleServer.ts
1095
+ var SCHEDULES_PAGE_LIMIT = 25;
1096
+ async function loadAgentIndex(client) {
1097
+ const agents = await drainAgentsList(client);
1098
+ const idToName = /* @__PURE__ */ new Map();
1099
+ const nameToId = /* @__PURE__ */ new Map();
1100
+ for (const agent of agents) {
1101
+ idToName.set(agent.id, agent.name);
1102
+ nameToId.set(agent.name, agent.id);
1103
+ }
1104
+ return { idToName, nameToId };
1105
+ }
1106
+ function resolveAgentName(agentId, index) {
1107
+ const byId = index.idToName.get(agentId);
1108
+ if (byId != null) return byId;
1109
+ if (index.nameToId.has(agentId)) return agentId;
1110
+ throw new Error(`Unknown agent: ${agentId}`);
1111
+ }
1112
+ function collectAgentIds(req) {
1113
+ const ids = [];
1114
+ if (req?.agentIds != null) {
1115
+ for (const id of req.agentIds) {
1116
+ if (id !== "") ids.push(id);
1117
+ }
1118
+ }
1119
+ if (req?.agentId != null && req.agentId !== "") ids.push(req.agentId);
1120
+ return [...new Set(ids)];
1121
+ }
1122
+ function wireStatus(manifest) {
1123
+ return manifest.status ?? "active";
1124
+ }
1125
+ function toUiSchedule(wire, index) {
1126
+ const agentId = index.nameToId.get(wire.agentName) ?? wire.agentName;
1127
+ return {
1128
+ id: wire.id,
1129
+ name: wire.name,
1130
+ agentId,
1131
+ agentName: wire.agentName,
1132
+ task: wire.manifest.task,
1133
+ cron: wire.manifest.cron,
1134
+ timezone: wire.manifest.timezone ?? "UTC",
1135
+ status: wireStatus(wire.manifest),
1136
+ lastRunAt: null,
1137
+ createdBySubject: wire.createdBySubject
1138
+ };
1139
+ }
1140
+ function toWireManifest(input) {
1141
+ return {
1142
+ task: input.task,
1143
+ cron: input.cron,
1144
+ timezone: input.timezone ?? "UTC",
1145
+ status: input.status ?? "active"
1146
+ };
1147
+ }
1148
+ function toIsoInstant(value) {
1149
+ if (value instanceof Date) return value.toISOString();
1150
+ return value;
1151
+ }
1152
+ function toUiScheduleRun(wire) {
1153
+ return {
1154
+ id: wire.id,
1155
+ scheduleId: wire.scheduleId,
1156
+ name: wire.name,
1157
+ scheduledFor: toIsoInstant(wire.scheduledFor),
1158
+ status: wire.status,
1159
+ triggeredAt: wire.triggeredAt == null ? null : toIsoInstant(wire.triggeredAt),
1160
+ triggeredBy: wire.createdBySubject.subjectDisplayName || wire.createdBySubject.subjectId
1161
+ };
1162
+ }
1163
+ function createScheduleServer(options) {
1164
+ const { client } = options;
1165
+ return {
1166
+ async listSchedules(req) {
1167
+ const index = await loadAgentIndex(client);
1168
+ const agentIds = collectAgentIds(req);
1169
+ const agentNames = agentIds.length === 0 ? void 0 : agentIds.map((id) => resolveAgentName(id, index)).join(",");
1170
+ const limit = Math.min(Math.max(req?.limit ?? SCHEDULES_PAGE_LIMIT, 1), SCHEDULES_PAGE_LIMIT);
1171
+ const page = await client.schedules.list({
1172
+ limit,
1173
+ ...req?.pageToken === void 0 || req.pageToken === "" ? {} : { pageToken: req.pageToken },
1174
+ ...agentNames === void 0 ? {} : { agentNames }
1175
+ });
1176
+ return toListResult(page, (row) => toUiSchedule(row, index));
1177
+ },
1178
+ async getSchedule({ id }) {
1179
+ const index = await loadAgentIndex(client);
1180
+ const { data } = await client.schedules.get(id);
1181
+ return toUiSchedule(data, index);
1182
+ },
1183
+ async createSchedule(req) {
1184
+ const index = await loadAgentIndex(client);
1185
+ const agentName = resolveAgentName(req.agentId, index);
1186
+ const { data } = await client.schedules.create({
1187
+ agentName,
1188
+ name: req.name,
1189
+ manifest: toWireManifest(req)
1190
+ });
1191
+ return toUiSchedule(data, index);
1192
+ },
1193
+ async updateSchedule(req) {
1194
+ const index = await loadAgentIndex(client);
1195
+ const { data } = await client.schedules.update(req.id, {
1196
+ name: req.name,
1197
+ manifest: toWireManifest(req)
1198
+ });
1199
+ return toUiSchedule(data, index);
1200
+ },
1201
+ async deleteSchedule({ id }) {
1202
+ await client.schedules.delete(id);
1203
+ },
1204
+ async listScheduleRuns({ scheduleId }) {
1205
+ const { data } = await client.schedules.listRuns(scheduleId);
1206
+ return data.map(toUiScheduleRun);
1207
+ },
1208
+ async createScheduleRun(req) {
1209
+ const { data } = await client.schedules.createRun({ scheduleId: req.scheduleId });
1210
+ return toUiScheduleRun(data);
1211
+ }
1212
+ };
1213
+ }
1214
+
820
1215
  // src/plugins/trueforge-agent-server-adapter/index.ts
821
1216
  function createTrueForgeAgentUIServer(options = {}) {
822
- const { catalog: catalogOverride, ...clientOptions } = options;
1217
+ const { catalog: catalogOverride, permissions, ...clientOptions } = options;
823
1218
  const client = createTrueForgeClient(clientOptions);
824
1219
  const catalog = catalogOverride ?? {
825
1220
  modelCatalog: createModelProviderCatalog(client),
@@ -830,16 +1225,24 @@ function createTrueForgeAgentUIServer(options = {}) {
830
1225
  return createTrueFoundryServer({
831
1226
  chatServer: createHarnessChatServer({ client }),
832
1227
  ...createHarnessBuilderServer({ client }),
833
- catalog
1228
+ catalog,
1229
+ sessions: createHarnessAgentSessionsServer({ ...clientOptions, client }),
1230
+ metrics: createHarnessAgentMetricsServer({ ...clientOptions, client }),
1231
+ schedules: createScheduleServer({ client }),
1232
+ permissions: permissions ?? createHarnessPermissionsServer({ client })
834
1233
  });
835
1234
  }
836
1235
  export {
837
1236
  configFromHarness,
838
1237
  createConnectorCatalog,
1238
+ createHarnessAgentMetricsServer,
1239
+ createHarnessAgentSessionsServer,
839
1240
  createHarnessBuilderServer,
840
1241
  createHarnessChatServer,
1242
+ createHarnessPermissionsServer,
841
1243
  createModelProviderCatalog,
842
1244
  createSandboxProviderCatalog,
1245
+ createScheduleServer,
843
1246
  createSkillCatalog,
844
1247
  createTrueForgeAgentUIServer,
845
1248
  createTrueForgeClient,