@opengeni/api-router 0.12.1 → 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 CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  validateToolRefs,
20
20
  withDefaultEnabledCapabilityMcpTools,
21
21
  workflowIdForSession
22
- } from "./chunk-S2N4252E.js";
22
+ } from "./chunk-3JR6L6NJ.js";
23
23
  export {
24
24
  API_MAX_REQUEST_BODY_BYTES,
25
25
  allowedCorsOrigin,
@@ -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(() => null);
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(() => ({ tools: [] }));
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 guardedFetch = guardedMcpFetch(input.deps.settings, undiciFetch);
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 process = await getRetainedProcess(db, {
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 (!process || process.state !== "active" || process.ownerActorKind !== "direct" || process.accountId !== ctx.accountId || process.leaseId !== pty.leaseId || process.sandboxGroupId !== pty.sandboxGroupId || process.parentAdmissionId !== pty.openAdmissionId || process.leaseEpoch !== pty.leaseEpoch || process.providerBackend !== pty.providerBackend || process.providerInstanceId !== pty.providerInstanceId || process.routeKind !== pty.routeKind || process.routeTargetId !== pty.routeTargetId || process.routeEpoch !== pty.routeEpoch || process.providerSessionId !== pty.execSessionId || // Only a persistable home backend can currently be reconstructed by an
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
- process.routeTargetId !== null || handle.lease.id !== process.leaseId || handle.lease.sandboxGroupId !== process.sandboxGroupId || handle.lease.leaseEpoch !== process.leaseEpoch || handle.lease.backend !== process.providerBackend || handle.lease.instanceId !== process.providerInstanceId) {
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: process.id, providerSessionId: process.providerSessionId },
13327
+ process: { id: process2.id, providerSessionId: process2.providerSessionId },
13287
13328
  backend: {
13288
13329
  sandboxId: null,
13289
- leaseEpoch: process.leaseEpoch,
13290
- providerInstanceId: process.providerInstanceId,
13291
- activeEpoch: process.routeEpoch
13330
+ leaseEpoch: process2.leaseEpoch,
13331
+ providerInstanceId: process2.providerInstanceId,
13332
+ activeEpoch: process2.routeEpoch
13292
13333
  }
13293
13334
  });
13294
- return process;
13335
+ return process2;
13295
13336
  };
13296
- const emitPtyExited = async (ctx, ptyId, process) => {
13337
+ const emitPtyExited = async (ctx, ptyId, process2) => {
13297
13338
  const exited = {
13298
13339
  ptyId,
13299
- exitCode: process.exitCode,
13300
- reason: process.state === "exited" ? "exit" : "lost"
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 process = retained ? await getRetainedProcess(db, {
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 || !process || process.state !== "active" || process.ownerActorKind !== "direct" || process.providerSessionId !== execSessionId || process.routeTargetId !== null || process.leaseId !== handle.lease.id || process.sandboxGroupId !== handle.lease.sandboxGroupId || process.leaseEpoch !== handle.lease.leaseEpoch || process.providerBackend !== handle.lease.backend || process.providerInstanceId !== handle.lease.instanceId) {
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: process.leaseId,
14937
- sandboxGroupId: process.sandboxGroupId,
14938
- retainedProcessId: process.id,
14939
- openAdmissionId: process.parentAdmissionId,
14940
- execSessionId: process.providerSessionId,
14941
- leaseEpoch: process.leaseEpoch,
14942
- providerBackend: process.providerBackend,
14943
- providerInstanceId: process.providerInstanceId,
14944
- routeKind: process.routeKind,
14945
- routeTargetId: process.routeTargetId,
14946
- routeEpoch: process.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(deps.settings, deps.settings.openaiModel),
16498
- allowedModels: configuredAllowedModels(deps.settings),
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(deps.settings).map(projectClientModel),
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-S2N4252E.js.map
17224
+ //# sourceMappingURL=chunk-3JR6L6NJ.js.map