@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 +1 -1
- package/dist/{chunk-VQCBJV4P.js → chunk-V4IDX7VJ.js} +106 -49
- package/dist/{chunk-VQCBJV4P.js.map → chunk-V4IDX7VJ.js.map} +1 -1
- package/dist/index.js +1 -1
- package/dist/integrations/github-lens-connect.d.ts +1 -1
- package/dist/integrations/marketplace-plugin.d.ts +26 -26
- package/dist/mcp/scheduled-task-view.d.ts +3 -3
- package/dist/workspace-tool-gateway.d.ts +2 -1
- package/package.json +19 -19
- package/src/codemode.ts +4 -8
- package/src/mcp/server.ts +64 -20
- package/src/routes/sessions.ts +24 -0
- package/src/workspace-tool-gateway.ts +11 -10
package/dist/app.js
CHANGED
|
@@ -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 =
|
|
480
|
-
|
|
481
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
9021
|
-
|
|
9022
|
-
|
|
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 (
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
27190
|
-
|
|
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
|
|
29798
|
-
|
|
29799
|
-
|
|
29800
|
-
|
|
29801
|
-
|
|
29802
|
-
|
|
29803
|
-
|
|
29804
|
-
|
|
29805
|
-
|
|
29806
|
-
|
|
29807
|
-
|
|
29808
|
-
|
|
29809
|
-
|
|
29810
|
-
|
|
29811
|
-
|
|
29812
|
-
|
|
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
|
|
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
|
|
94055
|
-
getWorkspaceArtifactContentRef as
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
105879
|
+
//# sourceMappingURL=chunk-V4IDX7VJ.js.map
|