@opengeni/api-router 0.12.0 → 0.12.2
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/dist/app.js +1 -1
- package/dist/{chunk-S2N4252E.js → chunk-3JR6L6NJ.js} +74 -32
- package/dist/chunk-3JR6L6NJ.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +10 -10
- package/src/app.ts +7 -3
- package/src/mcp/server.ts +20 -0
- package/src/mcp/toolspace.ts +44 -3
- package/dist/chunk-S2N4252E.js.map +0 -1
package/dist/app.js
CHANGED
|
@@ -3,7 +3,8 @@ import {
|
|
|
3
3
|
canonicalizeConfiguredModelId as canonicalizeConfiguredModelId2,
|
|
4
4
|
configuredAllowedModels,
|
|
5
5
|
configuredAllowedReasoningEfforts,
|
|
6
|
-
configuredModels as configuredModels2
|
|
6
|
+
configuredModels as configuredModels2,
|
|
7
|
+
withCodexCatalogProvider as withCodexCatalogProvider2
|
|
7
8
|
} from "@opengeni/config";
|
|
8
9
|
import {
|
|
9
10
|
ClientConfig,
|
|
@@ -3049,6 +3050,19 @@ function registerToolspaceProxyTools(server, surface) {
|
|
|
3049
3050
|
if (!surface) {
|
|
3050
3051
|
return;
|
|
3051
3052
|
}
|
|
3053
|
+
if (surface.tools.length === 0) {
|
|
3054
|
+
server.registerTool(
|
|
3055
|
+
"__opengeni_empty_toolspace_surface__",
|
|
3056
|
+
{
|
|
3057
|
+
description: "Internal disabled placeholder for an empty Toolspace surface.",
|
|
3058
|
+
inputSchema: z4.object({})
|
|
3059
|
+
},
|
|
3060
|
+
async () => ({
|
|
3061
|
+
content: [{ type: "text", text: '{"unavailable":true}' }]
|
|
3062
|
+
})
|
|
3063
|
+
).disable();
|
|
3064
|
+
return;
|
|
3065
|
+
}
|
|
3052
3066
|
for (const tool of surface.tools) {
|
|
3053
3067
|
server.registerTool(
|
|
3054
3068
|
tool.name,
|
|
@@ -4887,13 +4901,25 @@ async function resolveToolListing(input) {
|
|
|
4887
4901
|
sessionId,
|
|
4888
4902
|
rootSessionId,
|
|
4889
4903
|
turn: activeTurn
|
|
4890
|
-
}).catch(() =>
|
|
4904
|
+
}).catch((error) => {
|
|
4905
|
+
deps.observability?.warn("toolspace upstream connection failed", {
|
|
4906
|
+
serverId,
|
|
4907
|
+
...toolspaceErrorAttributes(error)
|
|
4908
|
+
});
|
|
4909
|
+
return null;
|
|
4910
|
+
});
|
|
4891
4911
|
if (!connection) {
|
|
4892
4912
|
aggregateBudget.replace(serverId, []);
|
|
4893
4913
|
return;
|
|
4894
4914
|
}
|
|
4895
4915
|
try {
|
|
4896
|
-
const listed = await connection.client.listTools(void 0, toolspaceRequestOptions(config)).catch(() =>
|
|
4916
|
+
const listed = await connection.client.listTools(void 0, toolspaceRequestOptions(config)).catch((error) => {
|
|
4917
|
+
deps.observability?.warn("toolspace upstream tool list failed", {
|
|
4918
|
+
serverId,
|
|
4919
|
+
...toolspaceErrorAttributes(error)
|
|
4920
|
+
});
|
|
4921
|
+
return { tools: [] };
|
|
4922
|
+
});
|
|
4897
4923
|
let boundedTools;
|
|
4898
4924
|
try {
|
|
4899
4925
|
boundedTools = assertMcpToolListWithinBounds(listed.tools);
|
|
@@ -4980,7 +5006,11 @@ async function settingsWithSessionMcpServersForToolspace(deps, workspaceId, sess
|
|
|
4980
5006
|
};
|
|
4981
5007
|
}
|
|
4982
5008
|
async function connectToolspaceServer(input) {
|
|
4983
|
-
const
|
|
5009
|
+
const useBunNativeFetch = !!process.versions.bun;
|
|
5010
|
+
const mcpFetchImpl = useBunNativeFetch ? globalThis.fetch.bind(globalThis) : undiciFetch;
|
|
5011
|
+
const guardedFetch = guardedMcpFetch(input.deps.settings, mcpFetchImpl, {
|
|
5012
|
+
...useBunNativeFetch ? { pinResolvedDestination: false } : {}
|
|
5013
|
+
});
|
|
4984
5014
|
const baseFetch = input.config.connectionRef ? connectionBrokerFetch(guardedFetch, input) : guardedFetch;
|
|
4985
5015
|
const client = new Client(
|
|
4986
5016
|
{ name: `opengeni-toolspace-${input.config.id}`, version: "1.0.0" },
|
|
@@ -5186,6 +5216,17 @@ function toolspaceAuditSummary(value) {
|
|
|
5186
5216
|
sha256: createHash2("sha256").update(serialized).digest("hex")
|
|
5187
5217
|
};
|
|
5188
5218
|
}
|
|
5219
|
+
function toolspaceErrorAttributes(error) {
|
|
5220
|
+
if (!(error instanceof Error)) {
|
|
5221
|
+
return { errorClass: typeof error };
|
|
5222
|
+
}
|
|
5223
|
+
const code = error.code;
|
|
5224
|
+
return {
|
|
5225
|
+
errorClass: error.name,
|
|
5226
|
+
...typeof code === "string" ? { errorCode: code } : {},
|
|
5227
|
+
...error.message ? { errorMessage: error.message.replaceAll(/[\r\n]+/gu, " ").slice(0, 512) } : {}
|
|
5228
|
+
};
|
|
5229
|
+
}
|
|
5189
5230
|
async function reserveExactAttemptCall(deps, grant, authority) {
|
|
5190
5231
|
const reservation = await reserveToolspaceCallForAttempt(deps.db, {
|
|
5191
5232
|
accountId: grant.accountId,
|
|
@@ -13270,34 +13311,34 @@ function registerSessionRoutes(app, deps) {
|
|
|
13270
13311
|
message: "durable interactive terminals require a session-home provider lease"
|
|
13271
13312
|
});
|
|
13272
13313
|
}
|
|
13273
|
-
const
|
|
13314
|
+
const process2 = await getRetainedProcess(db, {
|
|
13274
13315
|
workspaceId: ctx.workspaceId,
|
|
13275
13316
|
sessionId: ctx.session.id,
|
|
13276
13317
|
processId: pty.retainedProcessId
|
|
13277
13318
|
});
|
|
13278
|
-
if (!
|
|
13319
|
+
if (!process2 || process2.state !== "active" || process2.ownerActorKind !== "direct" || process2.accountId !== ctx.accountId || process2.leaseId !== pty.leaseId || process2.sandboxGroupId !== pty.sandboxGroupId || process2.parentAdmissionId !== pty.openAdmissionId || process2.leaseEpoch !== pty.leaseEpoch || process2.providerBackend !== pty.providerBackend || process2.providerInstanceId !== pty.providerInstanceId || process2.routeKind !== pty.routeKind || process2.routeTargetId !== pty.routeTargetId || process2.routeEpoch !== pty.routeEpoch || process2.providerSessionId !== pty.execSessionId || // Only a persistable home backend can currently be reconstructed by an
|
|
13279
13320
|
// API request without consulting the mutable active pointer.
|
|
13280
|
-
|
|
13321
|
+
process2.routeTargetId !== null || handle.lease.id !== process2.leaseId || handle.lease.sandboxGroupId !== process2.sandboxGroupId || handle.lease.leaseEpoch !== process2.leaseEpoch || handle.lease.backend !== process2.providerBackend || handle.lease.instanceId !== process2.providerInstanceId) {
|
|
13281
13322
|
throw new HTTPException22(409, {
|
|
13282
13323
|
message: "pty retained-process identity is stale; reopen the terminal"
|
|
13283
13324
|
});
|
|
13284
13325
|
}
|
|
13285
13326
|
handle.routingSession.adoptRetainedProcess({
|
|
13286
|
-
process: { id:
|
|
13327
|
+
process: { id: process2.id, providerSessionId: process2.providerSessionId },
|
|
13287
13328
|
backend: {
|
|
13288
13329
|
sandboxId: null,
|
|
13289
|
-
leaseEpoch:
|
|
13290
|
-
providerInstanceId:
|
|
13291
|
-
activeEpoch:
|
|
13330
|
+
leaseEpoch: process2.leaseEpoch,
|
|
13331
|
+
providerInstanceId: process2.providerInstanceId,
|
|
13332
|
+
activeEpoch: process2.routeEpoch
|
|
13292
13333
|
}
|
|
13293
13334
|
});
|
|
13294
|
-
return
|
|
13335
|
+
return process2;
|
|
13295
13336
|
};
|
|
13296
|
-
const emitPtyExited = async (ctx, ptyId,
|
|
13337
|
+
const emitPtyExited = async (ctx, ptyId, process2) => {
|
|
13297
13338
|
const exited = {
|
|
13298
13339
|
ptyId,
|
|
13299
|
-
exitCode:
|
|
13300
|
-
reason:
|
|
13340
|
+
exitCode: process2.exitCode,
|
|
13341
|
+
reason: process2.state === "exited" ? "exit" : "lost"
|
|
13301
13342
|
};
|
|
13302
13343
|
await appendAndPublishEvents5(db, bus, ctx.workspaceId, ctx.session.id, [
|
|
13303
13344
|
{ type: "terminal.pty.exited", payload: exited }
|
|
@@ -14919,12 +14960,12 @@ function registerSessionRoutes(app, deps) {
|
|
|
14919
14960
|
const opened = await service.ptyOpen(req, ptyId);
|
|
14920
14961
|
const execSessionId = opened.execSessionId;
|
|
14921
14962
|
const retained = execSessionId === null ? null : handle.routingSession.retainedProcessIdentity(execSessionId);
|
|
14922
|
-
const
|
|
14963
|
+
const process2 = retained ? await getRetainedProcess(db, {
|
|
14923
14964
|
workspaceId: ctx.workspaceId,
|
|
14924
14965
|
sessionId: ctx.session.id,
|
|
14925
14966
|
processId: retained.id
|
|
14926
14967
|
}) : null;
|
|
14927
|
-
if (execSessionId === null || !retained || !
|
|
14968
|
+
if (execSessionId === null || !retained || !process2 || process2.state !== "active" || process2.ownerActorKind !== "direct" || process2.providerSessionId !== execSessionId || process2.routeTargetId !== null || process2.leaseId !== handle.lease.id || process2.sandboxGroupId !== handle.lease.sandboxGroupId || process2.leaseEpoch !== handle.lease.leaseEpoch || process2.providerBackend !== handle.lease.backend || process2.providerInstanceId !== handle.lease.instanceId) {
|
|
14928
14969
|
if (execSessionId !== null && handle.routingSession.hasRetainedProcess(execSessionId)) {
|
|
14929
14970
|
await drainOpenedPty(handle, execSessionId);
|
|
14930
14971
|
}
|
|
@@ -14933,17 +14974,17 @@ function registerSessionRoutes(app, deps) {
|
|
|
14933
14974
|
});
|
|
14934
14975
|
}
|
|
14935
14976
|
const identity = {
|
|
14936
|
-
leaseId:
|
|
14937
|
-
sandboxGroupId:
|
|
14938
|
-
retainedProcessId:
|
|
14939
|
-
openAdmissionId:
|
|
14940
|
-
execSessionId:
|
|
14941
|
-
leaseEpoch:
|
|
14942
|
-
providerBackend:
|
|
14943
|
-
providerInstanceId:
|
|
14944
|
-
routeKind:
|
|
14945
|
-
routeTargetId:
|
|
14946
|
-
routeEpoch:
|
|
14977
|
+
leaseId: process2.leaseId,
|
|
14978
|
+
sandboxGroupId: process2.sandboxGroupId,
|
|
14979
|
+
retainedProcessId: process2.id,
|
|
14980
|
+
openAdmissionId: process2.parentAdmissionId,
|
|
14981
|
+
execSessionId: process2.providerSessionId,
|
|
14982
|
+
leaseEpoch: process2.leaseEpoch,
|
|
14983
|
+
providerBackend: process2.providerBackend,
|
|
14984
|
+
providerInstanceId: process2.providerInstanceId,
|
|
14985
|
+
routeKind: process2.routeKind,
|
|
14986
|
+
routeTargetId: process2.routeTargetId,
|
|
14987
|
+
routeEpoch: process2.routeEpoch
|
|
14947
14988
|
};
|
|
14948
14989
|
try {
|
|
14949
14990
|
await insertPtySession(db, {
|
|
@@ -16489,18 +16530,19 @@ function createApp(deps) {
|
|
|
16489
16530
|
);
|
|
16490
16531
|
app.get("/v1/config/client", (c) => {
|
|
16491
16532
|
c.header("cache-control", "no-store");
|
|
16533
|
+
const catalogSettings = deps.settings.codexSubscriptionEnabled ? withCodexCatalogProvider2(deps.settings) : deps.settings;
|
|
16492
16534
|
return c.json(
|
|
16493
16535
|
ClientConfig.parse({
|
|
16494
16536
|
deploymentRevision: deps.settings.deploymentRevision,
|
|
16495
16537
|
apiContractRevision: OPENGENI_API_CONTRACT_REVISION,
|
|
16496
16538
|
...deps.settings.serverVersion ? { serverVersion: deps.settings.serverVersion } : {},
|
|
16497
|
-
defaultModel: canonicalizeConfiguredModelId2(
|
|
16498
|
-
allowedModels: configuredAllowedModels(
|
|
16539
|
+
defaultModel: canonicalizeConfiguredModelId2(catalogSettings, catalogSettings.openaiModel),
|
|
16540
|
+
allowedModels: configuredAllowedModels(catalogSettings),
|
|
16499
16541
|
// Provider-grouped model list for the picker. configuredModels() carries the
|
|
16500
16542
|
// union of the built-in allow-list and every registry provider's models, in
|
|
16501
16543
|
// selection order (default model first); project each to the client-safe
|
|
16502
16544
|
// ClientModel shape (ConfiguredModel.providerId → ClientModel.provider).
|
|
16503
|
-
models: configuredModels2(
|
|
16545
|
+
models: configuredModels2(catalogSettings).map(projectClientModel),
|
|
16504
16546
|
defaultReasoningEffort: deps.settings.openaiReasoningEffort,
|
|
16505
16547
|
allowedReasoningEfforts: configuredAllowedReasoningEfforts(deps.settings),
|
|
16506
16548
|
mcpServers: deps.settings.mcpServers.map((server) => ({
|
|
@@ -17179,4 +17221,4 @@ export {
|
|
|
17179
17221
|
withDefaultEnabledCapabilityMcpTools,
|
|
17180
17222
|
workflowIdForSession2 as workflowIdForSession
|
|
17181
17223
|
};
|
|
17182
|
-
//# sourceMappingURL=chunk-
|
|
17224
|
+
//# sourceMappingURL=chunk-3JR6L6NJ.js.map
|