@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.
- package/CHANGELOG.md +48 -0
- package/README.md +14 -6
- package/dist/AgentCodeSnippets-NZOFJE57.js +74 -0
- package/dist/AgentCodeSnippets-NZOFJE57.js.map +1 -0
- package/dist/AgentMetricChart-JPU3MFQ2.js +15 -0
- package/dist/AgentOverview-EEBHJC32.js +167 -0
- package/dist/AgentOverview-EEBHJC32.js.map +1 -0
- package/dist/AgentSessionEventTimeline-26Z6IB3B.js +79 -0
- package/dist/AgentSessionEventTimeline-26Z6IB3B.js.map +1 -0
- package/dist/AgentSessionEventTimelineChart-CGCU7WBK.js +504 -0
- package/dist/AgentSessionEventTimelineChart-CGCU7WBK.js.map +1 -0
- package/dist/AgentSessions-3MPDZASK.js +275 -0
- package/dist/AgentSessions-3MPDZASK.js.map +1 -0
- package/dist/{ConnectorSettings-FXQ5B7TN.js → ConnectorSettings-MXFRWWR6.js} +8 -6
- package/dist/{ConnectorSettings-FXQ5B7TN.js.map → ConnectorSettings-MXFRWWR6.js.map} +1 -1
- package/dist/{DockLayout-LBNQJZNF.js → DockLayout-LM4AFMFY.js} +11 -10
- package/dist/{DockLayout-LBNQJZNF.js.map → DockLayout-LM4AFMFY.js.map} +1 -1
- package/dist/DrawerLayout-JR3O6RRB.js +184 -0
- package/dist/DrawerLayout-JR3O6RRB.js.map +1 -0
- package/dist/{ModelSettings-4L4LOQJA.js → ModelSettings-G7IFNC2Y.js} +8 -6
- package/dist/{ModelSettings-4L4LOQJA.js.map → ModelSettings-G7IFNC2Y.js.map} +1 -1
- package/dist/OpenUiFenceBlock-2TV5TQ6P.js +9 -0
- package/dist/OpenUiFenceBlock-2TV5TQ6P.js.map +1 -0
- package/dist/{SandboxSettings-Z4ZG6ZX4.js → SandboxSettings-NXAANMAX.js} +8 -6
- package/dist/{SandboxSettings-Z4ZG6ZX4.js.map → SandboxSettings-NXAANMAX.js.map} +1 -1
- package/dist/SchedulesPage-KKLUDO6B.js +15 -0
- package/dist/SchedulesPage-KKLUDO6B.js.map +1 -0
- package/dist/{SettingsBuilder-WF7ZWKQW.js → SettingsBuilder-L34IQ56S.js} +26 -22
- package/dist/SettingsBuilder-L34IQ56S.js.map +1 -0
- package/dist/{ShellRouteSync-T4WLY57Q.js → ShellRouteSync-CEBETGEJ.js} +95 -22
- package/dist/ShellRouteSync-CEBETGEJ.js.map +1 -0
- package/dist/SidebarLayout-A2HJPPHS.js +308 -0
- package/dist/SidebarLayout-A2HJPPHS.js.map +1 -0
- package/dist/{SkillSettings-3EPPC3IT.js → SkillSettings-FGGMSUNO.js} +8 -6
- package/dist/{SkillSettings-3EPPC3IT.js.map → SkillSettings-FGGMSUNO.js.map} +1 -1
- package/dist/{TrueForgeUIWithRouter-NZ4FGPE4.js → TrueForgeUIWithRouter-MZVJWJMB.js} +14 -10
- package/dist/{TrueForgeUIWithRouter-NZ4FGPE4.js.map → TrueForgeUIWithRouter-MZVJWJMB.js.map} +1 -1
- package/dist/{WidgetLayout-3QZ357FL.js → WidgetLayout-6QM45OQQ.js} +17 -13
- package/dist/WidgetLayout-6QM45OQQ.js.map +1 -0
- package/dist/chunk-2XPPBEYF.js +74 -0
- package/dist/chunk-2XPPBEYF.js.map +1 -0
- package/dist/chunk-6O6FWUDW.js +1376 -0
- package/dist/chunk-6O6FWUDW.js.map +1 -0
- package/dist/chunk-7Z2C2K7F.js +578 -0
- package/dist/chunk-7Z2C2K7F.js.map +1 -0
- package/dist/{chunk-WREC7D54.js → chunk-CYHJDKFB.js} +115 -32
- package/dist/chunk-CYHJDKFB.js.map +1 -0
- package/dist/chunk-DJUFS2BW.js +27 -0
- package/dist/chunk-DJUFS2BW.js.map +1 -0
- package/dist/chunk-DMMZSZTN.js +252 -0
- package/dist/chunk-DMMZSZTN.js.map +1 -0
- package/dist/chunk-FJW36PD7.js +180 -0
- package/dist/chunk-FJW36PD7.js.map +1 -0
- package/dist/chunk-M62XY4NC.js +555 -0
- package/dist/chunk-M62XY4NC.js.map +1 -0
- package/dist/{chunk-B52K63AW.js → chunk-MPNSO7E6.js} +2 -2
- package/dist/{chunk-CFLVPV5M.js → chunk-QC42MLAK.js} +7 -2
- package/dist/chunk-QC42MLAK.js.map +1 -0
- package/dist/chunk-RDXBMTP5.js +32 -0
- package/dist/chunk-RDXBMTP5.js.map +1 -0
- package/dist/chunk-SFZNIO6U.js +18 -0
- package/dist/chunk-SFZNIO6U.js.map +1 -0
- package/dist/chunk-U7KURWW3.js +840 -0
- package/dist/chunk-U7KURWW3.js.map +1 -0
- package/dist/chunk-WVE3F724.js +200 -0
- package/dist/chunk-WVE3F724.js.map +1 -0
- package/dist/{chunk-FJ5RSSMA.js → chunk-XAU7QFG3.js} +178 -36
- package/dist/chunk-XAU7QFG3.js.map +1 -0
- package/dist/chunk-Y6S4OVVQ.js +16 -0
- package/dist/chunk-Y6S4OVVQ.js.map +1 -0
- package/dist/chunk-ZKNUMH2M.js +119 -0
- package/dist/chunk-ZKNUMH2M.js.map +1 -0
- package/dist/chunk-ZTMKFZQ3.js +13214 -0
- package/dist/chunk-ZTMKFZQ3.js.map +1 -0
- package/dist/{createTrueFoundryServer-B72bU-J7.d.ts → createTrueFoundryServer-CmZnBh_l.d.ts} +15 -4
- package/dist/index.d.ts +1002 -22
- package/dist/index.js +689 -67
- package/dist/index.js.map +1 -1
- package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +552 -8
- package/dist/plugins/trueforge-agent-server-adapter/index.js +503 -188
- package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +8 -7
- package/dist/DrawerLayout-Q6UK4VMI.js +0 -159
- package/dist/DrawerLayout-Q6UK4VMI.js.map +0 -1
- package/dist/OpenUiFenceBlock-6UIIAVBX.js +0 -9
- package/dist/SettingsBuilder-WF7ZWKQW.js.map +0 -1
- package/dist/ShellRouteSync-T4WLY57Q.js.map +0 -1
- package/dist/SidebarLayout-3WZ3CVON.js +0 -256
- package/dist/SidebarLayout-3WZ3CVON.js.map +0 -1
- package/dist/WidgetLayout-3QZ357FL.js.map +0 -1
- package/dist/chunk-36KOSC2J.js +0 -567
- package/dist/chunk-36KOSC2J.js.map +0 -1
- package/dist/chunk-3S6KHO7H.js +0 -2121
- package/dist/chunk-3S6KHO7H.js.map +0 -1
- package/dist/chunk-7L63OK3O.js +0 -91
- package/dist/chunk-7L63OK3O.js.map +0 -1
- package/dist/chunk-CFLVPV5M.js.map +0 -1
- package/dist/chunk-FJ5RSSMA.js.map +0 -1
- package/dist/chunk-OSV3HI5M.js +0 -6891
- package/dist/chunk-OSV3HI5M.js.map +0 -1
- package/dist/chunk-WQULF5AT.js +0 -460
- package/dist/chunk-WQULF5AT.js.map +0 -1
- package/dist/chunk-WREC7D54.js.map +0 -1
- package/dist/chunk-YIWUG6MC.js +0 -101
- package/dist/chunk-YIWUG6MC.js.map +0 -1
- package/dist/chunk-ZXOADNF3.js +0 -75
- package/dist/chunk-ZXOADNF3.js.map +0 -1
- /package/dist/{OpenUiFenceBlock-6UIIAVBX.js.map → AgentMetricChart-JPU3MFQ2.js.map} +0 -0
- /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-
|
|
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/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (
|
|
12
|
-
return
|
|
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
|
-
|
|
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
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
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
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
120
|
-
const
|
|
121
|
-
return
|
|
47
|
+
async getCharts() {
|
|
48
|
+
const { data } = await client.internal.metrics.listCharts();
|
|
49
|
+
return data.charts;
|
|
122
50
|
},
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
|
57
|
+
return data.meters;
|
|
153
58
|
},
|
|
154
|
-
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
|
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/
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
400
|
-
|
|
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
|
|
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
|
-
...
|
|
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,
|