@opengeni/api-router 2.12.4-canary.3 → 2.13.0-canary.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/dist/app.js CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  withDefaultEnabledCapabilityMcpTools,
25
25
  workflowIdForSession,
26
26
  workspaceActorContextExempt
27
- } from "./chunk-VQCBJV4P.js";
27
+ } from "./chunk-V4IDX7VJ.js";
28
28
  export {
29
29
  API_MAX_REQUEST_BODY_BYTES,
30
30
  allowedCorsOrigin,
@@ -156,6 +156,7 @@ function feedbackHttpError(error) {
156
156
  }
157
157
 
158
158
  // src/codemode.ts
159
+ import { siteRequestHeaders } from "@opengeni/contracts/site-session-http";
159
160
  import {
160
161
  codemodeDispatchSubject,
161
162
  decodeCodemodeDispatchAck,
@@ -476,14 +477,9 @@ async function codemodeSessionRequest(deps, grant, request, path) {
476
477
  const target = new URL(request.url);
477
478
  const rewritten = siteSessionPath(path, authority.workspaceId, request.method);
478
479
  const url = new URL(rewritten, target.origin);
479
- const headers = new Headers({
480
- authorization: `Bearer ${token}`,
481
- [OPENGENI_API_CONTRACT_HEADER]: OPENGENI_API_CONTRACT_REVISION
482
- });
483
- for (const name of ["content-type", "accept", "last-event-id"]) {
484
- const value = request.headers.get(name);
485
- if (value) headers.set(name, value);
486
- }
480
+ const headers = siteRequestHeaders(request.headers);
481
+ headers.set("authorization", `Bearer ${token}`);
482
+ headers.set(OPENGENI_API_CONTRACT_HEADER, OPENGENI_API_CONTRACT_REVISION);
487
483
  return new Request(url, {
488
484
  method: request.method,
489
485
  headers,
@@ -5766,6 +5762,7 @@ import { requireLimit as requireLimit10 } from "@opengeni/core";
5766
5762
 
5767
5763
  // src/mcp/server.ts
5768
5764
  import {
5765
+ getAttemptToolCatalog as getAttemptToolCatalog2,
5769
5766
  createChannel,
5770
5767
  listChannels,
5771
5768
  getChannel,
@@ -6142,8 +6139,8 @@ import {
6142
6139
  upsertSessionGoalWithEvent,
6143
6140
  RigChangeTransitionError,
6144
6141
  createWorkspaceArtifact,
6145
- getWorkspaceArtifact as getWorkspaceArtifact3,
6146
- getWorkspaceArtifactContentRef,
6142
+ getWorkspaceArtifact as getWorkspaceArtifact2,
6143
+ getWorkspaceArtifactContentRef as getWorkspaceArtifactContentRef2,
6147
6144
  listWorkspaceArtifacts,
6148
6145
  publishWorkspaceArtifactVersion,
6149
6146
  rollbackWorkspaceArtifact,
@@ -7979,7 +7976,7 @@ import {
7979
7976
  requireWorkspace,
7980
7977
  withCodexAppsRequestAuthorization,
7981
7978
  consumeToolGatewayApproval,
7982
- getWorkspaceArtifact,
7979
+ getWorkspaceArtifactContentRef,
7983
7980
  issueToolGatewayApproval,
7984
7981
  ToolGatewayApprovalOperationStartedError,
7985
7982
  ToolGatewayApprovalRateLimitError,
@@ -9015,14 +9012,18 @@ function throwWorkspaceToolGatewayHttpError(error) {
9015
9012
  }
9016
9013
  throw error;
9017
9014
  }
9018
- async function requireWorkspaceSiteToolAuthorization(db, grant, context) {
9015
+ async function requireWorkspaceSiteToolAuthorization(db, grant, context, resolveVersion = getWorkspaceArtifactContentRef) {
9019
9016
  try {
9020
- const detail = await getWorkspaceArtifact(db, grant.workspaceId, context.siteArtifactId);
9021
- const currentVersion = detail.artifact.currentVersion;
9022
- const requested = currentVersion?.requestedTools.some(
9017
+ const { status, version: version2 } = await resolveVersion(
9018
+ db,
9019
+ grant.workspaceId,
9020
+ context.siteArtifactId,
9021
+ context.siteVersionId
9022
+ );
9023
+ const requested = version2.requestedTools.some(
9023
9024
  (identity) => identity.serverId === context.identity.serverId && identity.toolName === context.identity.toolName
9024
9025
  );
9025
- if (detail.artifact.status !== "active" || currentVersion?.id !== context.siteVersionId || !requested) {
9026
+ if (status !== "active" || version2.id !== context.siteVersionId || !requested) {
9026
9027
  throw new HTTPException8(403, { message: "site_tool_not_authorized" });
9027
9028
  }
9028
9029
  } catch (error) {
@@ -9815,7 +9816,7 @@ function registerFileRoutes(app, deps) {
9815
9816
  const workspaceId = c.req.param("workspaceId");
9816
9817
  const grant = await requireAccessGrant5(c, deps, workspaceId, "files:read");
9817
9818
  const artifactId2 = retainedArtifactId(c.req.param("artifactId"));
9818
- const artifact = await getWorkspaceArtifact2(db, {
9819
+ const artifact = await getWorkspaceArtifact(db, {
9819
9820
  accountId: grant.accountId,
9820
9821
  workspaceId,
9821
9822
  subjectId: await fileAuthoritySubjectIdForGrant(deps, grant),
@@ -9830,7 +9831,7 @@ function registerFileRoutes(app, deps) {
9830
9831
  const workspaceId = c.req.param("workspaceId");
9831
9832
  const grant = await requireAccessGrant5(c, deps, workspaceId, "files:read");
9832
9833
  const artifactId2 = retainedArtifactId(c.req.param("artifactId"));
9833
- const artifact = await getWorkspaceArtifact2(db, {
9834
+ const artifact = await getWorkspaceArtifact(db, {
9834
9835
  accountId: grant.accountId,
9835
9836
  workspaceId,
9836
9837
  subjectId: await fileAuthoritySubjectIdForGrant(deps, grant),
@@ -10115,7 +10116,7 @@ function retainedArtifactMetadata(artifact) {
10115
10116
  }
10116
10117
  return retainedArtifactUnavailable(file.id, "unsupported");
10117
10118
  }
10118
- async function getWorkspaceArtifact2(db, input) {
10119
+ async function getWorkspaceArtifact(db, input) {
10119
10120
  const generated = await getGeneratedImageArtifact(db, input.workspaceId, input.artifactId);
10120
10121
  if (generated) {
10121
10122
  return { file: generated.file, metadata: retainedGeneratedImageMetadata(generated) };
@@ -27186,8 +27187,8 @@ function registerWorkspaceArtifactTools(server, deps, grant, sessionId, json) {
27186
27187
  await authorize();
27187
27188
  if (!deps.objectStorage) throw new Error("Object storage is not configured");
27188
27189
  const [rawDetail, ref] = await Promise.all([
27189
- getWorkspaceArtifact3(deps.db, grant.workspaceId, artifactId2),
27190
- getWorkspaceArtifactContentRef(deps.db, grant.workspaceId, artifactId2, versionId)
27190
+ getWorkspaceArtifact2(deps.db, grant.workspaceId, artifactId2),
27191
+ getWorkspaceArtifactContentRef2(deps.db, grant.workspaceId, artifactId2, versionId)
27191
27192
  ]);
27192
27193
  const sourceAuthorizations = /* @__PURE__ */ new Map();
27193
27194
  const canReadSourceSession = (sourceSessionId) => {
@@ -29777,6 +29778,25 @@ function registerCapabilityDiscoveryTools(server, deps, grant, sessionId, json)
29777
29778
  const authorize = async () => {
29778
29779
  await authorizeFirstPartySession(deps, grant, sessionId, "session.first_party_mcp.call");
29779
29780
  };
29781
+ const setupProjections = async (items) => {
29782
+ const availableServerIds = /* @__PURE__ */ new Set();
29783
+ if (items.some((item) => item.enabled && item.connectionRef?.subjectScope === "subject")) {
29784
+ const claims = exactAgentCommandContext(grant, sessionId);
29785
+ const attemptCatalog = await getAttemptToolCatalog2(deps.db, {
29786
+ accountId: grant.accountId,
29787
+ workspaceId: grant.workspaceId,
29788
+ attemptId: claims.callerAttemptId
29789
+ });
29790
+ if (attemptCatalog?.sessionId === sessionId && attemptCatalog.turnId === claims.callerTurnId && attemptCatalog.executionGeneration === claims.callerExecutionGeneration) {
29791
+ for (const entry2 of attemptCatalog.entries) availableServerIds.add(entry2.identity.serverId);
29792
+ }
29793
+ }
29794
+ return await Promise.all(
29795
+ items.map(
29796
+ (item) => capabilitySetupProjection(deps, grant.workspaceId, item, availableServerIds)
29797
+ )
29798
+ );
29799
+ };
29780
29800
  server.registerTool(
29781
29801
  "capability_catalog_search",
29782
29802
  {
@@ -29794,25 +29814,24 @@ function registerCapabilityDiscoveryTools(server, deps, grant, sessionId, json)
29794
29814
  query,
29795
29815
  limit ?? 8
29796
29816
  );
29797
- const matches = await Promise.all(
29798
- ranked.map(async ({ item, matchedOn }) => ({
29799
- capabilityId: item.id,
29800
- name: item.name,
29801
- description: item.description,
29802
- kind: item.kind,
29803
- source: item.source,
29804
- category: item.category,
29805
- tags: item.tags.slice(0, 16),
29806
- providerDomain: item.providerDomain,
29807
- authKind: item.authKind,
29808
- tier: item.tier,
29809
- matchedOn,
29810
- setup: {
29811
- ...await capabilitySetupProjection(deps, grant.workspaceId, item),
29812
- requiredVariables: capabilityRequiredVariables(item)
29813
- }
29814
- }))
29815
- );
29817
+ const setups = await setupProjections(ranked.map(({ item }) => item));
29818
+ const matches = ranked.map(({ item, matchedOn }, index) => ({
29819
+ capabilityId: item.id,
29820
+ name: item.name,
29821
+ description: item.description,
29822
+ kind: item.kind,
29823
+ source: item.source,
29824
+ category: item.category,
29825
+ tags: item.tags.slice(0, 16),
29826
+ providerDomain: item.providerDomain,
29827
+ authKind: item.authKind,
29828
+ tier: item.tier,
29829
+ matchedOn,
29830
+ setup: {
29831
+ ...setups[index],
29832
+ requiredVariables: capabilityRequiredVariables(item)
29833
+ }
29834
+ }));
29816
29835
  return json({ query, matches });
29817
29836
  }
29818
29837
  );
@@ -29834,7 +29853,8 @@ function registerCapabilityDiscoveryTools(server, deps, grant, sessionId, json)
29834
29853
  if (!item || !capabilityCatalogItemIsTrustedForExposure(item)) {
29835
29854
  throw new Error("Unknown or untrusted capability; search the catalog again.");
29836
29855
  }
29837
- const setup = await capabilitySetupProjection(deps, grant.workspaceId, item);
29856
+ const [setup] = await setupProjections([item]);
29857
+ if (!setup) throw new Error("Capability setup projection is unavailable.");
29838
29858
  if (setup.status === "ready") {
29839
29859
  return json({
29840
29860
  capabilityId: item.id,
@@ -29890,7 +29910,7 @@ function registerCapabilityDiscoveryTools(server, deps, grant, sessionId, json)
29890
29910
  }
29891
29911
  );
29892
29912
  }
29893
- async function capabilitySetupProjection(deps, workspaceId, item) {
29913
+ async function capabilitySetupProjection(deps, workspaceId, item, availableServerIds) {
29894
29914
  if (item.id === "api:github-app" || item.surfaceType === "first_party_github") {
29895
29915
  const missing = githubAppMissingSettings(deps.settings);
29896
29916
  if (missing.length > 0) {
@@ -29925,6 +29945,20 @@ async function capabilitySetupProjection(deps, workspaceId, item) {
29925
29945
  detail: "A workspace admin must designate an authorized Codex Apps subscription."
29926
29946
  };
29927
29947
  }
29948
+ if (item.enabled && item.connectionRef?.subjectScope === "subject") {
29949
+ if (item.runtime.mcpServerId && availableServerIds.has(item.runtime.mcpServerId)) {
29950
+ return {
29951
+ status: "ready",
29952
+ action: null,
29953
+ detail: "This capability has tools available in this turn."
29954
+ };
29955
+ }
29956
+ return {
29957
+ status: "authorization_required",
29958
+ action: "connect",
29959
+ detail: "This capability is enabled, but its personal account is not available in this turn. The account owner must review access using Use in this conversation, then send a new message. Shared conversations require acknowledgement that results are visible to workspace members."
29960
+ };
29961
+ }
29928
29962
  if (item.enabled) {
29929
29963
  return {
29930
29964
  status: "ready",
@@ -86024,6 +86058,7 @@ import {
86024
86058
  requireAccessGrant as requireAccessGrant33,
86025
86059
  requireAccessGrantAuthorization as requireAccessGrantAuthorization23,
86026
86060
  requireFreshAccessGrant as requireFreshAccessGrant2,
86061
+ rotateSessionMcpCredentialsForRequest,
86027
86062
  hasVerifiedOwningUserAuthorization,
86028
86063
  requirePermission as requirePermission8,
86029
86064
  requireSessionAuthorization as requireSessionAuthorization11,
@@ -88601,6 +88636,26 @@ function registerSessionRoutes(app, deps) {
88601
88636
  await listSessionTurns(db, workspaceId, sessionId, boundedLimit(c.req.query("limit")))
88602
88637
  );
88603
88638
  });
88639
+ app.post("/v1/workspaces/:workspaceId/sessions/:sessionId/mcp-credentials/rotate", async (c) => {
88640
+ const workspaceId = c.req.param("workspaceId");
88641
+ const authorization = await requireAccessGrantAuthorization23(
88642
+ c,
88643
+ deps,
88644
+ workspaceId,
88645
+ "sessions:control"
88646
+ );
88647
+ const payload = await c.req.json().catch(() => null);
88648
+ c.header("cache-control", "private, no-store");
88649
+ return c.json(
88650
+ await rotateSessionMcpCredentialsForRequest(
88651
+ deps,
88652
+ authorization,
88653
+ c.req.param("sessionId"),
88654
+ payload,
88655
+ (tx) => requireFreshAccessGrant2(c, { ...deps, db: tx }, workspaceId, "sessions:control")
88656
+ )
88657
+ );
88658
+ });
88604
88659
  app.get("/v1/workspaces/:workspaceId/sessions/:sessionId/queue", async (c) => {
88605
88660
  const workspaceId = c.req.param("workspaceId");
88606
88661
  await requireAccessGrant33(c, deps, workspaceId, "sessions:read");
@@ -89942,6 +89997,8 @@ function sessionAuthorizationOperationForHttp(method, pathname, sessionId) {
89942
89997
  if (suffix === "/channel" && verb === "PUT") return "session.channel.write";
89943
89998
  if (suffix === "/variable-sets" && verb === "PUT") return "session.variable_sets.write";
89944
89999
  if (suffix === "/tool-policy" && verb === "PUT") return "session.tool_policy.write";
90000
+ if (suffix === "/mcp-credentials/rotate" && verb === "POST")
90001
+ return "session.mcp.credentials.rotate";
89945
90002
  if (/^\/mcp-servers\/[^/]+\/approval-policy$/.test(suffix) && verb === "PATCH") {
89946
90003
  return "session.mcp.approval_policy.write";
89947
90004
  }
@@ -94051,8 +94108,8 @@ import {
94051
94108
  } from "@opengeni/core";
94052
94109
  import {
94053
94110
  createWorkspaceArtifact as createWorkspaceArtifact2,
94054
- getWorkspaceArtifact as getWorkspaceArtifact4,
94055
- getWorkspaceArtifactContentRef as getWorkspaceArtifactContentRef2,
94111
+ getWorkspaceArtifact as getWorkspaceArtifact3,
94112
+ getWorkspaceArtifactContentRef as getWorkspaceArtifactContentRef3,
94056
94113
  listWorkspaceArtifacts as listWorkspaceArtifacts2,
94057
94114
  nestedPostgresSqlState as nestedPostgresSqlState6,
94058
94115
  publishWorkspaceArtifactVersion as publishWorkspaceArtifactVersion2,
@@ -94174,7 +94231,7 @@ function registerWorkspaceArtifactRoutes(app, deps) {
94174
94231
  throw new HTTPException81(503, {
94175
94232
  message: "Object storage is not configured"
94176
94233
  });
94177
- const ref = await getWorkspaceArtifactContentRef2(
94234
+ const ref = await getWorkspaceArtifactContentRef3(
94178
94235
  deps.db,
94179
94236
  workspaceId,
94180
94237
  artifactId(context),
@@ -94258,7 +94315,7 @@ function registerWorkspaceArtifactRoutes(app, deps) {
94258
94315
  const workspaceId = context.req.param("workspaceId");
94259
94316
  const grant = await requireAccessGrant42(context, deps, workspaceId, "artifacts:read");
94260
94317
  try {
94261
- const detail = await getWorkspaceArtifact4(deps.db, workspaceId, artifactId(context));
94318
+ const detail = await getWorkspaceArtifact3(deps.db, workspaceId, artifactId(context));
94262
94319
  return context.json(
94263
94320
  WorkspaceArtifactDetailResponse.parse(
94264
94321
  await projectWorkspaceArtifactDetailProvenance(
@@ -94278,7 +94335,7 @@ function registerWorkspaceArtifactRoutes(app, deps) {
94278
94335
  throw new HTTPException81(503, {
94279
94336
  message: "Object storage is not configured"
94280
94337
  });
94281
- const ref = await getWorkspaceArtifactContentRef2(
94338
+ const ref = await getWorkspaceArtifactContentRef3(
94282
94339
  deps.db,
94283
94340
  workspaceId,
94284
94341
  artifactId(context),
@@ -94318,7 +94375,7 @@ function registerWorkspaceArtifactRoutes(app, deps) {
94318
94375
  });
94319
94376
  const parsedVersion = parseVersionId(context.req.query("versionId"));
94320
94377
  try {
94321
- const ref = await getWorkspaceArtifactContentRef2(
94378
+ const ref = await getWorkspaceArtifactContentRef3(
94322
94379
  deps.db,
94323
94380
  workspaceId,
94324
94381
  artifactId(context),
@@ -105819,4 +105876,4 @@ export {
105819
105876
  withDefaultEnabledCapabilityMcpTools,
105820
105877
  workflowIdForSession4 as workflowIdForSession
105821
105878
  };
105822
- //# sourceMappingURL=chunk-VQCBJV4P.js.map
105879
+ //# sourceMappingURL=chunk-V4IDX7VJ.js.map