@opengeni/api-router 0.23.1 → 0.30.0
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.d.ts +3 -2
- package/dist/app.js +5 -3
- package/dist/auth/canonical-human-session-admission.d.ts +27 -0
- package/dist/browser-auth-broker.d.ts +20 -0
- package/dist/browser-controller-authority.d.ts +61 -0
- package/dist/browser-network-route.d.ts +8 -0
- package/dist/browser-state-authority.d.ts +27 -0
- package/dist/{chunk-T4T2PGU4.js → chunk-2PQMSRCB.js} +37891 -17463
- package/dist/chunk-2PQMSRCB.js.map +1 -0
- package/dist/codemode.d.ts +23 -0
- package/dist/controller-data-plane.d.ts +12 -0
- package/dist/editable-artifact-live-hints.d.ts +11 -0
- package/dist/editable-artifact-native-kernel.d.ts +37 -0
- package/dist/editable-artifact-office-import.d.ts +22 -0
- package/dist/editable-artifact-production.d.ts +29 -0
- package/dist/editable-artifact-websocket.d.ts +49 -0
- package/dist/editable-artifact-workspace-files.d.ts +23 -0
- package/dist/github-browser-flow.d.ts +6 -0
- package/dist/http/auth.d.ts +1 -1
- package/dist/http/cors.d.ts +1 -0
- package/dist/http/sse.d.ts +18 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1796 -22
- package/dist/index.js.map +1 -1
- package/dist/integrations/api-integrations.d.ts +24 -0
- package/dist/integrations/atlassian.d.ts +176 -0
- package/dist/integrations/fiken.d.ts +233 -0
- package/dist/integrations/github-skill-source.d.ts +5 -0
- package/dist/integrations/google-drive.d.ts +85 -0
- package/dist/integrations/oauth-client.d.ts +22 -1
- package/dist/integrations/provider-oauth.d.ts +17 -0
- package/dist/integrations/slack-bot.d.ts +175 -1
- package/dist/integrations/slack-interactions.d.ts +24 -6
- package/dist/integrations/social-api.d.ts +2 -1
- package/dist/interaction-holder-heartbeat.d.ts +17 -0
- package/dist/interaction-metrics.d.ts +11 -0
- package/dist/mcp/editable-artifact-query-schema.d.ts +4 -0
- package/dist/mcp/editable-artifacts.d.ts +13 -0
- package/dist/mcp/scheduled-task-view.d.ts +168 -0
- package/dist/mcp/server.d.ts +16 -4
- package/dist/memory-slack-delivery.d.ts +9 -0
- package/dist/model-catalog.d.ts +1 -0
- package/dist/routes/api-integrations.d.ts +8 -0
- package/dist/routes/browser-identities.d.ts +5 -0
- package/dist/routes/browser-sessions.d.ts +6 -0
- package/dist/routes/canonical-human-identities.d.ts +3 -0
- package/dist/routes/channels.d.ts +3 -0
- package/dist/routes/company-profile.d.ts +3 -0
- package/dist/routes/computer-sessions.d.ts +6 -0
- package/dist/routes/editable-artifacts.d.ts +44 -0
- package/dist/routes/integration-facets.d.ts +3 -0
- package/dist/routes/interaction-resources.d.ts +5 -0
- package/dist/routes/memory-slack-publications.d.ts +6 -0
- package/dist/routes/organization-memberships.d.ts +3 -0
- package/dist/routes/plugins.d.ts +8 -0
- package/dist/routes/sessions.d.ts +18 -2
- package/dist/routes/skills.d.ts +6 -0
- package/dist/routes/slack-task-policy.d.ts +3 -0
- package/dist/routes/supergrok.d.ts +3 -0
- package/dist/routes/video-generation.d.ts +3 -0
- package/dist/sandbox/channel-a.d.ts +62 -2
- package/dist/sandbox/machines.d.ts +2 -2
- package/dist/sandbox/metrics-ingestion.d.ts +6 -1
- package/dist/sandbox/viewer.d.ts +7 -3
- package/dist/slack-reaction-files.d.ts +27 -0
- package/dist/temporal-schedule-cleanup.d.ts +26 -0
- package/dist/transcription/providers/xai-subscription.d.ts +8 -0
- package/dist/xai-realtime.d.ts +26 -0
- package/dist/xai-subscription-auth.d.ts +23 -0
- package/package.json +20 -14
- package/src/app.ts +604 -64
- package/src/auth/canonical-human-session-admission.ts +116 -0
- package/src/auth/managed-auth.ts +101 -0
- package/src/browser-auth-broker.ts +155 -0
- package/src/browser-controller-authority.ts +186 -0
- package/src/browser-network-route.ts +34 -0
- package/src/browser-state-authority.ts +236 -0
- package/src/codemode.ts +186 -0
- package/src/controller-data-plane.ts +35 -0
- package/src/editable-artifact-live-hints.ts +64 -0
- package/src/editable-artifact-native-kernel.ts +659 -0
- package/src/editable-artifact-office-import.ts +230 -0
- package/src/editable-artifact-production.ts +419 -0
- package/src/editable-artifact-websocket.ts +311 -0
- package/src/editable-artifact-workspace-files.ts +186 -0
- package/src/github-browser-flow.ts +35 -6
- package/src/http/auth.ts +29 -9
- package/src/http/cors.ts +3 -0
- package/src/http/sse.ts +229 -5
- package/src/index.ts +119 -20
- package/src/integrations/api-integrations.ts +365 -0
- package/src/integrations/atlassian.ts +1621 -0
- package/src/integrations/fiken.ts +1230 -0
- package/src/integrations/github-skill-source.ts +142 -0
- package/src/integrations/google-drive.ts +1005 -64
- package/src/integrations/oauth-client.ts +123 -33
- package/src/integrations/provider-oauth.ts +756 -0
- package/src/integrations/slack-bot.ts +669 -11
- package/src/integrations/slack-interactions.ts +2063 -93
- package/src/integrations/social-api.ts +11 -0
- package/src/interaction-holder-heartbeat.ts +95 -0
- package/src/interaction-metrics.ts +159 -0
- package/src/mcp/documents.ts +146 -6
- package/src/mcp/editable-artifact-query-schema.ts +236 -0
- package/src/mcp/editable-artifacts.ts +448 -0
- package/src/mcp/scheduled-task-view.ts +34 -0
- package/src/mcp/server.ts +1756 -355
- package/src/memory-slack-delivery.ts +209 -0
- package/src/model-catalog.ts +19 -6
- package/src/routes/api-integrations.ts +410 -0
- package/src/routes/browser-identities.ts +160 -0
- package/src/routes/browser-sessions.ts +4482 -0
- package/src/routes/canonical-human-identities.ts +156 -0
- package/src/routes/channels.ts +90 -0
- package/src/routes/company-profile.ts +255 -0
- package/src/routes/computer-sessions.ts +1602 -0
- package/src/routes/connections.ts +421 -99
- package/src/routes/documents.ts +22 -3
- package/src/routes/editable-artifacts.ts +1159 -0
- package/src/routes/files.ts +106 -4
- package/src/routes/github.ts +18 -2
- package/src/routes/install.ts +7 -1
- package/src/routes/integration-facets.ts +258 -0
- package/src/routes/interaction-resources.ts +595 -0
- package/src/routes/memory-slack-publications.ts +216 -0
- package/src/routes/organization-memberships.ts +53 -0
- package/src/routes/packs.ts +437 -7
- package/src/routes/plugins.ts +752 -0
- package/src/routes/rigs.ts +77 -20
- package/src/routes/scheduled-tasks.ts +67 -40
- package/src/routes/sessions.ts +830 -278
- package/src/routes/skills.ts +256 -0
- package/src/routes/slack-task-policy.ts +115 -0
- package/src/routes/supergrok.ts +717 -0
- package/src/routes/transcription-recordings.ts +9 -2
- package/src/routes/transcriptions.ts +2 -1
- package/src/routes/video-generation.ts +162 -0
- package/src/routes/workspaces.ts +68 -28
- package/src/sandbox/channel-a.ts +750 -116
- package/src/sandbox/machines.ts +5 -5
- package/src/sandbox/metrics-ingestion.ts +121 -3
- package/src/sandbox/rematerialize.ts +35 -47
- package/src/sandbox/viewer.ts +39 -12
- package/src/slack-reaction-files.ts +181 -0
- package/src/temporal-schedule-cleanup.ts +135 -0
- package/src/transcription/providers/xai-subscription.ts +110 -0
- package/src/transcription/service.ts +17 -2
- package/src/xai-realtime.ts +216 -0
- package/src/xai-subscription-auth.ts +132 -0
- package/dist/chunk-T4T2PGU4.js.map +0 -1
- package/dist/mcp/toolspace.d.ts +0 -71
- package/src/mcp/toolspace.ts +0 -1190
package/src/app.ts
CHANGED
|
@@ -3,15 +3,19 @@ import {
|
|
|
3
3
|
configuredAllowedModels,
|
|
4
4
|
configuredAllowedReasoningEfforts,
|
|
5
5
|
configuredModels,
|
|
6
|
+
resolveFirstPartyMcpToolPolicy,
|
|
6
7
|
withCodexCatalogProvider,
|
|
8
|
+
withXaiSubscriptionCatalogProvider,
|
|
7
9
|
} from "@opengeni/config";
|
|
8
10
|
import {
|
|
9
11
|
ClientConfig,
|
|
12
|
+
CodemodeCallRequest,
|
|
10
13
|
ErrorEnvelope,
|
|
11
14
|
OPENGENI_API_CONTRACT_HEADER,
|
|
12
15
|
OPENGENI_API_CONTRACT_REVISION,
|
|
13
16
|
OPENGENI_CORRELATION_HEADER,
|
|
14
17
|
resolveWorkspaceMemoryEnabled,
|
|
18
|
+
resolveWorkspaceMemoryPromptMode,
|
|
15
19
|
VOICE_INPUT_ACCEPTED_MIME_TYPES,
|
|
16
20
|
TRANSCRIPTION_RECORDING_PROVIDER_SEGMENT_SECONDS,
|
|
17
21
|
type AccessGrant,
|
|
@@ -23,7 +27,18 @@ import {
|
|
|
23
27
|
indexDocumentNow,
|
|
24
28
|
type DocumentServices,
|
|
25
29
|
} from "@opengeni/documents";
|
|
26
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
CodemodeCallBudgetExceededError,
|
|
32
|
+
CodemodeOperationConflictError,
|
|
33
|
+
CodemodeOperationNotExecutableError,
|
|
34
|
+
CodemodePayloadTooLargeError,
|
|
35
|
+
CodemodeToolApprovalRequiredError,
|
|
36
|
+
CodemodeToolNotInCatalogError,
|
|
37
|
+
dbSql,
|
|
38
|
+
getWorkspace,
|
|
39
|
+
rlsContextForWorkspace,
|
|
40
|
+
withSessionRlsActorContext,
|
|
41
|
+
} from "@opengeni/db";
|
|
27
42
|
import { createObservability } from "@opengeni/observability";
|
|
28
43
|
import { createObjectStorage } from "@opengeni/storage";
|
|
29
44
|
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
@@ -39,6 +54,7 @@ import {
|
|
|
39
54
|
CodexCompactionV2ProviderLockedError,
|
|
40
55
|
hasPermission,
|
|
41
56
|
requireAccessGrant,
|
|
57
|
+
requireLiveAgentAttemptAuthorization,
|
|
42
58
|
requirePermission,
|
|
43
59
|
requireSessionAuthorization,
|
|
44
60
|
SessionAuthorizationDeniedError,
|
|
@@ -48,39 +64,69 @@ import { createManagedAuth } from "./auth/managed-auth";
|
|
|
48
64
|
import { createApiSandboxClient, makeResumeBoxById } from "./sandbox/access";
|
|
49
65
|
import { requireLimit } from "@opengeni/core";
|
|
50
66
|
import { buildOpenGeniMcpServer } from "./mcp/server";
|
|
51
|
-
import {
|
|
67
|
+
import {
|
|
68
|
+
CodemodeAuthorityError,
|
|
69
|
+
isCodemodeGrant,
|
|
70
|
+
readCodemodeOperation,
|
|
71
|
+
requireActiveCodemodeCatalog,
|
|
72
|
+
submitAndDispatchCodemodeCall,
|
|
73
|
+
} from "./codemode";
|
|
52
74
|
import { boundedMcpRequest, McpPayloadTooLargeError } from "@opengeni/runtime/mcp-network";
|
|
75
|
+
import {
|
|
76
|
+
BrowserControlProtocolError,
|
|
77
|
+
BrowserControlTransportError,
|
|
78
|
+
} from "@opengeni/runtime/sandbox";
|
|
53
79
|
import { requireAccessKey } from "./http/auth";
|
|
80
|
+
import { allowedCorsOrigin } from "./http/cors";
|
|
54
81
|
import { registerCapabilityRoutes } from "./routes/capabilities";
|
|
55
82
|
import { registerCatalogAssetRoutes } from "./routes/catalog-assets";
|
|
56
83
|
import { registerCodexRoutes } from "./routes/codex";
|
|
84
|
+
import { registerSuperGrokRoutes } from "./routes/supergrok";
|
|
57
85
|
import { registerConnectionRoutes } from "./routes/connections";
|
|
58
86
|
import { registerDocumentRoutes } from "./routes/documents";
|
|
59
87
|
import { registerEnrollmentRoutes } from "./routes/enrollments";
|
|
60
88
|
import { registerMachineRoutes } from "./routes/machines";
|
|
89
|
+
import { registerMemorySlackPublicationRoutes } from "./routes/memory-slack-publications";
|
|
61
90
|
import { registerEnvironmentRoutes } from "./routes/environments";
|
|
62
91
|
import { registerFileRoutes } from "./routes/files";
|
|
63
92
|
import { registerApiKeyRoutes } from "./routes/api-keys";
|
|
64
93
|
import { registerBillingRoutes } from "./routes/billing";
|
|
94
|
+
import { registerBrowserIdentityRoutes } from "./routes/browser-identities";
|
|
95
|
+
import { registerBrowserSessionRoutes } from "./routes/browser-sessions";
|
|
96
|
+
import { registerComputerSessionRoutes } from "./routes/computer-sessions";
|
|
65
97
|
import { registerGitHubRoutes } from "./routes/github";
|
|
66
98
|
import { registerInstallRoutes } from "./routes/install";
|
|
99
|
+
import { registerApiIntegrationRoutes } from "./routes/api-integrations";
|
|
100
|
+
import { registerIntegrationFacetRoutes } from "./routes/integration-facets";
|
|
101
|
+
import { registerInteractionResourceRoutes } from "./routes/interaction-resources";
|
|
67
102
|
import { registerPackRoutes } from "./routes/packs";
|
|
103
|
+
import { registerPluginRoutes } from "./routes/plugins";
|
|
104
|
+
import { registerSkillRoutes } from "./routes/skills";
|
|
105
|
+
import { registerChannelRoutes } from "./routes/channels";
|
|
68
106
|
import { registerRigRoutes } from "./routes/rigs";
|
|
69
107
|
import { registerScheduledTaskRoutes } from "./routes/scheduled-tasks";
|
|
70
108
|
import { registerSessionRoutes } from "./routes/sessions";
|
|
71
109
|
import { registerSocialRoutes } from "./routes/social";
|
|
72
110
|
import { registerWorkspaceRoutes } from "./routes/workspaces";
|
|
73
111
|
import { registerWorkspaceInstructionPolicyRoutes } from "./routes/workspace-instruction-policies";
|
|
112
|
+
import { registerCompanyProfileRoutes } from "./routes/company-profile";
|
|
113
|
+
import { registerSlackTaskPolicyRoutes } from "./routes/slack-task-policy";
|
|
74
114
|
import { registerWorkspaceStateRoutes } from "./routes/workspace-state";
|
|
75
115
|
import { registerWorkspaceArtifactRoutes } from "./routes/workspace-artifacts";
|
|
76
116
|
import { registerPreferenceRegistryRoutes } from "./routes/preference-registry";
|
|
77
117
|
import { registerInsightsRoutes } from "./routes/insights";
|
|
78
118
|
import { registerTranscriptionRoutes } from "./routes/transcriptions";
|
|
119
|
+
import { registerEditableArtifactRoutes } from "./routes/editable-artifacts";
|
|
120
|
+
import { registerVideoGenerationRoutes } from "./routes/video-generation";
|
|
121
|
+
import { registerCanonicalHumanIdentityRoutes } from "./routes/canonical-human-identities";
|
|
122
|
+
import { registerOrganizationMembershipRoutes } from "./routes/organization-memberships";
|
|
79
123
|
import { projectClientModel } from "./model-catalog";
|
|
80
124
|
import { createTranscriptionService } from "./transcription/service";
|
|
81
125
|
import { createFfmpegTranscriptionSegmenter } from "./transcription/segmenter";
|
|
82
126
|
import { registerSlackInteractionRoutes } from "./integrations/slack-interactions";
|
|
83
127
|
|
|
128
|
+
export { allowedCorsOrigin } from "./http/cors";
|
|
129
|
+
|
|
84
130
|
export type {
|
|
85
131
|
ApiRouteDeps,
|
|
86
132
|
AppDependencies,
|
|
@@ -102,7 +148,7 @@ export {
|
|
|
102
148
|
export { workflowIdForSession } from "@opengeni/core";
|
|
103
149
|
export { replaySessionEvents, sseSessionStream, sseWorkspaceControlStream } from "./http/sse";
|
|
104
150
|
|
|
105
|
-
export const API_MAX_REQUEST_BODY_BYTES =
|
|
151
|
+
export const API_MAX_REQUEST_BODY_BYTES = 32 * 1024 * 1024;
|
|
106
152
|
|
|
107
153
|
/** Effective Hono bodyLimit — API JSON ceiling or voice multipart + multipart overhead. */
|
|
108
154
|
export function apiRequestBodyLimitBytes(settings: {
|
|
@@ -249,12 +295,18 @@ export function createAppComposition(deps: AppDependencies): {
|
|
|
249
295
|
"Accept",
|
|
250
296
|
"Authorization",
|
|
251
297
|
"Content-Type",
|
|
298
|
+
"Range",
|
|
252
299
|
"X-OpenGeni-Access-Key",
|
|
253
300
|
"X-OpenGeni-Api-Contract",
|
|
254
301
|
"X-OpenGeni-Correlation-Id",
|
|
255
302
|
"X-OpenGeni-Subject",
|
|
256
303
|
],
|
|
257
|
-
exposeHeaders: [
|
|
304
|
+
exposeHeaders: [
|
|
305
|
+
"Accept-Ranges",
|
|
306
|
+
"Content-Range",
|
|
307
|
+
"X-OpenGeni-Api-Contract",
|
|
308
|
+
"X-OpenGeni-Correlation-Id",
|
|
309
|
+
],
|
|
258
310
|
};
|
|
259
311
|
const publicApiCors = cors({
|
|
260
312
|
...corsHeaders,
|
|
@@ -425,9 +477,12 @@ export function createAppComposition(deps: AppDependencies): {
|
|
|
425
477
|
|
|
426
478
|
app.get("/v1/config/client", async (c) => {
|
|
427
479
|
c.header("cache-control", "no-store");
|
|
428
|
-
const
|
|
480
|
+
const codexCatalogSettings = deps.settings.codexSubscriptionEnabled
|
|
429
481
|
? withCodexCatalogProvider(deps.settings)
|
|
430
482
|
: deps.settings;
|
|
483
|
+
const catalogSettings = deps.settings.supergrokSubscriptionEnabled
|
|
484
|
+
? withXaiSubscriptionCatalogProvider(codexCatalogSettings)
|
|
485
|
+
: codexCatalogSettings;
|
|
431
486
|
return c.json(
|
|
432
487
|
ClientConfig.parse({
|
|
433
488
|
deploymentRevision: deps.settings.deploymentRevision,
|
|
@@ -446,6 +501,7 @@ export function createAppComposition(deps: AppDependencies): {
|
|
|
446
501
|
id: server.id,
|
|
447
502
|
name: server.name ?? server.id,
|
|
448
503
|
})),
|
|
504
|
+
firstPartyMcpTools: resolveFirstPartyMcpToolPolicy(deps.settings),
|
|
449
505
|
fileUploads: {
|
|
450
506
|
enabled: objectStorage !== null,
|
|
451
507
|
maxSizeBytes: objectStorage?.maxSinglePutSizeBytes ?? 5_000_000_000,
|
|
@@ -485,6 +541,22 @@ export function createAppComposition(deps: AppDependencies): {
|
|
|
485
541
|
);
|
|
486
542
|
});
|
|
487
543
|
|
|
544
|
+
app.use("/v1/workspaces/:workspaceId/*", async (c, next) => {
|
|
545
|
+
const workspaceId = c.req.param("workspaceId");
|
|
546
|
+
if (workspaceRequestRequiresCodexAccountPrevalidation(c.req.raw)) {
|
|
547
|
+
const grant = await requireAccessGrant(c, routeDeps, workspaceId);
|
|
548
|
+
await validateCodexAccountTarget(c.req.raw);
|
|
549
|
+
await withAccessGrantSessionRlsContext(routeDeps, grant, next);
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
if (workspaceActorContextExempt(c.req.method, new URL(c.req.url).pathname)) {
|
|
553
|
+
await next();
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
const grant = await requireAccessGrant(c, routeDeps, workspaceId);
|
|
557
|
+
await withAccessGrantSessionRlsContext(routeDeps, grant, next);
|
|
558
|
+
});
|
|
559
|
+
|
|
488
560
|
app.all("/v1/workspaces/:workspaceId/mcp", async (c) => {
|
|
489
561
|
const workspaceId = c.req.param("workspaceId");
|
|
490
562
|
let boundedRequest: Request;
|
|
@@ -499,89 +571,138 @@ export function createAppComposition(deps: AppDependencies): {
|
|
|
499
571
|
throw error;
|
|
500
572
|
}
|
|
501
573
|
const grant = await requireMcpAccessGrant(c, routeDeps, workspaceId);
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
sessionId: boundSessionId,
|
|
511
|
-
operation: toolspaceGrant ? "session.toolspace.call" : "session.first_party_mcp.call",
|
|
512
|
-
surface: toolspaceGrant ? "toolspace" : "first_party_mcp",
|
|
513
|
-
});
|
|
514
|
-
} catch (error) {
|
|
515
|
-
if (error instanceof SessionAuthorizationDeniedError) {
|
|
516
|
-
throw new HTTPException(404, { message: "session not found" });
|
|
517
|
-
}
|
|
518
|
-
if (error instanceof SessionAuthorizationUnavailableError) {
|
|
519
|
-
throw new HTTPException(503, {
|
|
520
|
-
message: "session authorization is unavailable",
|
|
574
|
+
return await withAccessGrantSessionRlsContext(routeDeps, grant, async () => {
|
|
575
|
+
const boundSessionId = grant.metadata?.sessionId;
|
|
576
|
+
if (typeof boundSessionId === "string") {
|
|
577
|
+
try {
|
|
578
|
+
await requireSessionAuthorization(routeDeps, grant, {
|
|
579
|
+
sessionId: boundSessionId,
|
|
580
|
+
operation: "session.first_party_mcp.call",
|
|
581
|
+
surface: "first_party_mcp",
|
|
521
582
|
});
|
|
583
|
+
} catch (error) {
|
|
584
|
+
if (error instanceof SessionAuthorizationDeniedError) {
|
|
585
|
+
throw new HTTPException(404, { message: "session not found" });
|
|
586
|
+
}
|
|
587
|
+
if (error instanceof SessionAuthorizationUnavailableError) {
|
|
588
|
+
throw new HTTPException(503, {
|
|
589
|
+
message: "session authorization is unavailable",
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
throw error;
|
|
522
593
|
}
|
|
523
|
-
throw error;
|
|
524
594
|
}
|
|
595
|
+
const workspace = await getWorkspace(routeDeps.db, workspaceId);
|
|
596
|
+
const workspaceMemoryEnabled = resolveWorkspaceMemoryEnabled(workspace?.settings);
|
|
597
|
+
const workspaceMemoryPromptMode = resolveWorkspaceMemoryPromptMode(workspace?.settings);
|
|
598
|
+
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
599
|
+
enableJsonResponse: true,
|
|
600
|
+
});
|
|
601
|
+
const mcp = buildOpenGeniMcpServer(routeDeps, grant, {
|
|
602
|
+
requestOrigin: new URL(c.req.url).origin,
|
|
603
|
+
workspaceMemoryEnabled,
|
|
604
|
+
workspaceMemoryPromptMode,
|
|
605
|
+
});
|
|
606
|
+
await mcp.connect(transport);
|
|
607
|
+
return await transport.handleRequest(boundedRequest);
|
|
608
|
+
});
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
app.get("/v1/workspaces/:workspaceId/codemode/catalog", async (c) => {
|
|
612
|
+
const workspaceId = c.req.param("workspaceId");
|
|
613
|
+
const grant = await requireAccessGrant(c, routeDeps, workspaceId);
|
|
614
|
+
if (!isCodemodeGrant(grant)) {
|
|
615
|
+
throw new HTTPException(403, { message: "Codemode access denied" });
|
|
525
616
|
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
617
|
+
try {
|
|
618
|
+
return c.json((await requireActiveCodemodeCatalog(routeDeps, grant)).catalog);
|
|
619
|
+
} catch (error) {
|
|
620
|
+
throw codemodeHttpError(error);
|
|
621
|
+
}
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
app.post("/v1/workspaces/:workspaceId/codemode/calls", async (c) => {
|
|
625
|
+
const workspaceId = c.req.param("workspaceId");
|
|
626
|
+
const grant = await requireAccessGrant(c, routeDeps, workspaceId);
|
|
627
|
+
if (!isCodemodeGrant(grant)) {
|
|
628
|
+
throw new HTTPException(403, { message: "Codemode access denied" });
|
|
629
|
+
}
|
|
630
|
+
const parsed = CodemodeCallRequest.safeParse(await c.req.json().catch(() => null));
|
|
631
|
+
if (!parsed.success) {
|
|
632
|
+
throw new HTTPException(400, { message: "Invalid Codemode call" });
|
|
541
633
|
}
|
|
542
|
-
const workspace = await getWorkspace(routeDeps.db, workspaceId);
|
|
543
|
-
const workspaceMemoryEnabled = resolveWorkspaceMemoryEnabled(workspace?.settings);
|
|
544
|
-
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
545
|
-
enableJsonResponse: true,
|
|
546
|
-
});
|
|
547
|
-
const mcp = buildOpenGeniMcpServer(routeDeps, grant, {
|
|
548
|
-
requestOrigin: new URL(c.req.url).origin,
|
|
549
|
-
toolspace,
|
|
550
|
-
workspaceMemoryEnabled,
|
|
551
|
-
});
|
|
552
634
|
try {
|
|
553
|
-
await
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
635
|
+
const submission = await submitAndDispatchCodemodeCall(routeDeps, grant, parsed.data);
|
|
636
|
+
const terminal = ["completed", "failed", "outcome_unknown", "cancelled"].includes(
|
|
637
|
+
submission.operation.state,
|
|
638
|
+
);
|
|
639
|
+
return c.json(submission, terminal ? 200 : 202);
|
|
640
|
+
} catch (error) {
|
|
641
|
+
throw codemodeHttpError(error);
|
|
642
|
+
}
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
app.get("/v1/workspaces/:workspaceId/codemode/calls/:operationId", async (c) => {
|
|
646
|
+
const workspaceId = c.req.param("workspaceId");
|
|
647
|
+
const grant = await requireAccessGrant(c, routeDeps, workspaceId);
|
|
648
|
+
if (!isCodemodeGrant(grant)) {
|
|
649
|
+
throw new HTTPException(403, { message: "Codemode access denied" });
|
|
650
|
+
}
|
|
651
|
+
try {
|
|
652
|
+
const operation = await readCodemodeOperation(routeDeps, grant, c.req.param("operationId"));
|
|
653
|
+
if (!operation)
|
|
654
|
+
throw new HTTPException(404, {
|
|
655
|
+
message: "Codemode operation not found",
|
|
656
|
+
});
|
|
657
|
+
return c.json(operation);
|
|
658
|
+
} catch (error) {
|
|
659
|
+
if (error instanceof HTTPException) throw error;
|
|
660
|
+
throw codemodeHttpError(error);
|
|
557
661
|
}
|
|
558
662
|
});
|
|
559
663
|
|
|
560
664
|
registerFileRoutes(app, routeDeps);
|
|
561
665
|
registerApiKeyRoutes(app, routeDeps);
|
|
562
666
|
registerBillingRoutes(app, routeDeps);
|
|
667
|
+
registerBrowserIdentityRoutes(app, routeDeps);
|
|
668
|
+
registerBrowserSessionRoutes(app, routeDeps);
|
|
669
|
+
registerComputerSessionRoutes(app, routeDeps);
|
|
563
670
|
registerDocumentRoutes(app, routeDeps);
|
|
564
671
|
registerGitHubRoutes(app, routeDeps);
|
|
565
672
|
registerInstallRoutes(app, routeDeps);
|
|
673
|
+
registerInteractionResourceRoutes(app, routeDeps);
|
|
566
674
|
registerWorkspaceRoutes(app, routeDeps);
|
|
567
675
|
registerInsightsRoutes(app, routeDeps);
|
|
568
676
|
registerWorkspaceInstructionPolicyRoutes(app, routeDeps);
|
|
677
|
+
registerCompanyProfileRoutes(app, routeDeps);
|
|
678
|
+
registerSlackTaskPolicyRoutes(app, routeDeps);
|
|
569
679
|
registerWorkspaceStateRoutes(app, routeDeps);
|
|
680
|
+
registerMemorySlackPublicationRoutes(app, routeDeps);
|
|
570
681
|
registerWorkspaceArtifactRoutes(app, routeDeps);
|
|
571
682
|
registerPreferenceRegistryRoutes(app, routeDeps);
|
|
572
683
|
registerSocialRoutes(app, routeDeps);
|
|
573
684
|
registerConnectionRoutes(app, routeDeps);
|
|
574
685
|
registerCapabilityRoutes(app, routeDeps);
|
|
686
|
+
registerApiIntegrationRoutes(app, routeDeps);
|
|
687
|
+
registerIntegrationFacetRoutes(app, routeDeps);
|
|
575
688
|
registerCatalogAssetRoutes(app, routeDeps);
|
|
576
689
|
registerEnrollmentRoutes(app, routeDeps);
|
|
577
690
|
registerMachineRoutes(app, routeDeps);
|
|
578
691
|
registerEnvironmentRoutes(app, routeDeps);
|
|
692
|
+
registerChannelRoutes(app, routeDeps);
|
|
579
693
|
registerRigRoutes(app, routeDeps);
|
|
580
694
|
registerPackRoutes(app, routeDeps);
|
|
695
|
+
registerPluginRoutes(app, routeDeps);
|
|
696
|
+
registerSkillRoutes(app, routeDeps);
|
|
581
697
|
registerSessionRoutes(app, routeDeps);
|
|
582
698
|
registerScheduledTaskRoutes(app, routeDeps);
|
|
583
699
|
registerCodexRoutes(app, routeDeps);
|
|
700
|
+
registerSuperGrokRoutes(app, routeDeps);
|
|
584
701
|
registerTranscriptionRoutes(app, routeDeps);
|
|
702
|
+
registerEditableArtifactRoutes(app, routeDeps);
|
|
703
|
+
registerVideoGenerationRoutes(app, routeDeps);
|
|
704
|
+
registerCanonicalHumanIdentityRoutes(app, routeDeps);
|
|
705
|
+
registerOrganizationMembershipRoutes(app, routeDeps);
|
|
585
706
|
registerSlackInteractionRoutes(app, routeDeps);
|
|
586
707
|
|
|
587
708
|
app.notFound((c) => {
|
|
@@ -623,6 +744,7 @@ export function createAppComposition(deps: AppDependencies): {
|
|
|
623
744
|
? (boundedPublicMessage(apiError.message) ?? "Request failed.")
|
|
624
745
|
: publicErrorMessage(error, status),
|
|
625
746
|
retryable: apiError?.retryable ?? retryableHttpStatus(status),
|
|
747
|
+
...(mutationOutcomeUnknown(error, c.req.method) ? { outcomeUnknown: true } : {}),
|
|
626
748
|
requestId,
|
|
627
749
|
...(apiError?.details ? { details: apiError.details } : {}),
|
|
628
750
|
},
|
|
@@ -633,6 +755,14 @@ export function createAppComposition(deps: AppDependencies): {
|
|
|
633
755
|
return { app, routeDeps };
|
|
634
756
|
}
|
|
635
757
|
|
|
758
|
+
function mutationOutcomeUnknown(error: unknown, method: string): boolean {
|
|
759
|
+
if (method === "GET" || method === "HEAD" || method === "OPTIONS") return false;
|
|
760
|
+
const cause = error instanceof HTTPException ? error.cause : error;
|
|
761
|
+
return (
|
|
762
|
+
cause instanceof BrowserControlTransportError || cause instanceof BrowserControlProtocolError
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
|
|
636
766
|
export function appendVary(current: string | null, value: string): string {
|
|
637
767
|
const values = (current ?? "")
|
|
638
768
|
.split(",")
|
|
@@ -644,6 +774,74 @@ export function appendVary(current: string | null, value: string): string {
|
|
|
644
774
|
return values.join(", ");
|
|
645
775
|
}
|
|
646
776
|
|
|
777
|
+
const publicWorkspaceBrowserRoutePatterns = [
|
|
778
|
+
/^\/v1\/workspaces\/[^/]+\/github\/connect$/,
|
|
779
|
+
/^\/v1\/workspaces\/[^/]+\/github\/installations\/[^/]+\/configure$/,
|
|
780
|
+
/^\/v1\/workspaces\/[^/]+\/github\/installations\/select$/,
|
|
781
|
+
] as const;
|
|
782
|
+
|
|
783
|
+
export function workspaceActorContextExempt(method: string, pathname: string): boolean {
|
|
784
|
+
if (/^\/v1\/workspaces\/[^/]+\/mcp$/.test(pathname)) return true;
|
|
785
|
+
if (
|
|
786
|
+
method === "GET" &&
|
|
787
|
+
publicWorkspaceBrowserRoutePatterns.some((route) => route.test(pathname))
|
|
788
|
+
) {
|
|
789
|
+
return true;
|
|
790
|
+
}
|
|
791
|
+
return method === "POST" && /^\/v1\/workspaces\/[^/]+\/github\/installations$/.test(pathname);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
function workspaceRequestRequiresCodexAccountPrevalidation(request: Request): boolean {
|
|
795
|
+
return (
|
|
796
|
+
request.method === "POST" &&
|
|
797
|
+
/^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/codex-account$/.test(new URL(request.url).pathname)
|
|
798
|
+
);
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
async function validateCodexAccountTarget(request: Request): Promise<void> {
|
|
802
|
+
const body = (await request
|
|
803
|
+
.clone()
|
|
804
|
+
.json()
|
|
805
|
+
.catch(() => null)) as { target?: unknown } | null;
|
|
806
|
+
if (typeof body?.target !== "string" || body.target.length === 0) {
|
|
807
|
+
throw new HTTPException(400, {
|
|
808
|
+
message: 'target is required ("auto" or an account id)',
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
async function withAccessGrantSessionRlsContext<T>(
|
|
814
|
+
deps: ApiRouteDeps,
|
|
815
|
+
grant: AccessGrant,
|
|
816
|
+
fn: () => Promise<T>,
|
|
817
|
+
): Promise<T> {
|
|
818
|
+
if (grant.principalKind !== "agent_attempt") {
|
|
819
|
+
return await withSessionRlsActorContext({ subjectId: grant.subjectId }, fn);
|
|
820
|
+
}
|
|
821
|
+
const callerSessionId = grant.metadata?.sessionId;
|
|
822
|
+
if (typeof callerSessionId !== "string") {
|
|
823
|
+
throw new HTTPException(403, { message: "agent attempt authority is invalid" });
|
|
824
|
+
}
|
|
825
|
+
try {
|
|
826
|
+
const actor = await requireLiveAgentAttemptAuthorization(deps.db, grant, callerSessionId);
|
|
827
|
+
return await withSessionRlsActorContext(
|
|
828
|
+
{
|
|
829
|
+
subjectId: actor.subjectId,
|
|
830
|
+
initiatingHumanSubjectId: actor.initiatingHumanSubjectId,
|
|
831
|
+
},
|
|
832
|
+
fn,
|
|
833
|
+
);
|
|
834
|
+
} catch (error) {
|
|
835
|
+
if (error instanceof SessionAuthorizationDeniedError) {
|
|
836
|
+
throw new HTTPException(403, {
|
|
837
|
+
message: "agent attempt authority is invalid",
|
|
838
|
+
cause: error,
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
throw error;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
647
845
|
async function requireMcpAccessGrant(
|
|
648
846
|
c: Parameters<typeof requireAccessGrant>[0],
|
|
649
847
|
deps: ApiRouteDeps,
|
|
@@ -653,8 +851,8 @@ async function requireMcpAccessGrant(
|
|
|
653
851
|
if (hasPermission(grant.permissions, "workspace:read")) {
|
|
654
852
|
return grant;
|
|
655
853
|
}
|
|
656
|
-
if (
|
|
657
|
-
|
|
854
|
+
if (isCodemodeGrant(grant)) {
|
|
855
|
+
requirePermission(grant, "workspace:read");
|
|
658
856
|
}
|
|
659
857
|
// A worker-signed session-bound grant is allowed to reach the transport
|
|
660
858
|
// without inheriting broad workspace read access. The exact session
|
|
@@ -687,6 +885,48 @@ function clientAuthConfig(settings: AppDependencies["settings"]) {
|
|
|
687
885
|
return { mode: "none" as const };
|
|
688
886
|
}
|
|
689
887
|
|
|
888
|
+
function codemodeHttpError(error: unknown): HTTPException {
|
|
889
|
+
if (error instanceof SessionAuthorizationDeniedError) {
|
|
890
|
+
return new HTTPException(404, {
|
|
891
|
+
message: "session not found",
|
|
892
|
+
cause: error,
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
if (error instanceof SessionAuthorizationUnavailableError) {
|
|
896
|
+
return new HTTPException(503, {
|
|
897
|
+
message: "session authorization is unavailable",
|
|
898
|
+
cause: error,
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
if (
|
|
902
|
+
error instanceof CodemodeAuthorityError ||
|
|
903
|
+
error instanceof CodemodeOperationNotExecutableError
|
|
904
|
+
) {
|
|
905
|
+
return new HTTPException(409, { message: error.message, cause: error });
|
|
906
|
+
}
|
|
907
|
+
if (error instanceof CodemodeOperationConflictError) {
|
|
908
|
+
return new HTTPException(409, { message: error.message, cause: error });
|
|
909
|
+
}
|
|
910
|
+
if (error instanceof CodemodeCallBudgetExceededError) {
|
|
911
|
+
return new HTTPException(429, { message: error.message, cause: error });
|
|
912
|
+
}
|
|
913
|
+
if (error instanceof CodemodeToolNotInCatalogError) {
|
|
914
|
+
return new HTTPException(404, { message: error.message, cause: error });
|
|
915
|
+
}
|
|
916
|
+
if (error instanceof CodemodeToolApprovalRequiredError) {
|
|
917
|
+
return new HTTPException(409, { message: error.message, cause: error });
|
|
918
|
+
}
|
|
919
|
+
if (error instanceof CodemodePayloadTooLargeError) {
|
|
920
|
+
return new HTTPException(413, { message: error.message, cause: error });
|
|
921
|
+
}
|
|
922
|
+
return error instanceof HTTPException
|
|
923
|
+
? error
|
|
924
|
+
: new HTTPException(500, {
|
|
925
|
+
message: "Codemode request failed",
|
|
926
|
+
cause: error,
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
|
|
690
930
|
function clientAnalyticsConfig(settings: AppDependencies["settings"]) {
|
|
691
931
|
if (!settings.analyticsEnabled) {
|
|
692
932
|
return { consentRequired: true, providers: {} };
|
|
@@ -721,10 +961,6 @@ function structuredServicesHint(backend: string): {
|
|
|
721
961
|
return { fileSystem: hasBox, git: hasBox, terminalEvents: hasBox };
|
|
722
962
|
}
|
|
723
963
|
|
|
724
|
-
export function allowedCorsOrigin(pattern: string, origin: string): boolean {
|
|
725
|
-
return new RegExp(`^(?:${pattern})$`).test(origin);
|
|
726
|
-
}
|
|
727
|
-
|
|
728
964
|
function codexCompactionV2ProviderLockedError(
|
|
729
965
|
error: unknown,
|
|
730
966
|
): CodexCompactionV2ProviderLockedError | null {
|
|
@@ -875,7 +1111,10 @@ async function withTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T
|
|
|
875
1111
|
}
|
|
876
1112
|
}
|
|
877
1113
|
|
|
878
|
-
const routeLabelPatterns: Array<{
|
|
1114
|
+
const routeLabelPatterns: Array<{
|
|
1115
|
+
pattern: RegExp;
|
|
1116
|
+
label: string | ((match: RegExpMatchArray) => string);
|
|
1117
|
+
}> = [
|
|
879
1118
|
{ pattern: /^\/healthz$/, label: "/healthz" },
|
|
880
1119
|
{ pattern: /^\/readyz$/, label: "/readyz" },
|
|
881
1120
|
{ pattern: /^\/traffic-readyz$/, label: "/traffic-readyz" },
|
|
@@ -891,6 +1130,22 @@ const routeLabelPatterns: Array<{ pattern: RegExp; label: string }> = [
|
|
|
891
1130
|
pattern: /^\/v1\/workspaces\/[^/]+\/codex\/status$/,
|
|
892
1131
|
label: "/v1/workspaces/:workspaceId/codex/status",
|
|
893
1132
|
},
|
|
1133
|
+
{
|
|
1134
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/supergrok\/connect\/(start|poll)$/,
|
|
1135
|
+
label: (match) => `/v1/workspaces/:workspaceId/supergrok/connect/${match[1]}`,
|
|
1136
|
+
},
|
|
1137
|
+
{
|
|
1138
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/supergrok\/(status|accounts|settings)$/,
|
|
1139
|
+
label: (match) => `/v1/workspaces/:workspaceId/supergrok/${match[1]}`,
|
|
1140
|
+
},
|
|
1141
|
+
{
|
|
1142
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/supergrok\/accounts\/[^/]+\/(activate|allocator)$/,
|
|
1143
|
+
label: (match) => `/v1/workspaces/:workspaceId/supergrok/accounts/:accountId/${match[1]}`,
|
|
1144
|
+
},
|
|
1145
|
+
{
|
|
1146
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/supergrok\/accounts\/[^/]+$/,
|
|
1147
|
+
label: "/v1/workspaces/:workspaceId/supergrok/accounts/:accountId",
|
|
1148
|
+
},
|
|
894
1149
|
{
|
|
895
1150
|
pattern: /^\/v1\/workspaces\/[^/]+\/codex\/usage$/,
|
|
896
1151
|
label: "/v1/workspaces/:workspaceId/codex/usage",
|
|
@@ -937,6 +1192,154 @@ const routeLabelPatterns: Array<{ pattern: RegExp; label: string }> = [
|
|
|
937
1192
|
pattern: /^\/v1\/workspaces\/[^/]+\/control-events\/stream$/,
|
|
938
1193
|
label: "/v1/workspaces/:workspaceId/control-events/stream",
|
|
939
1194
|
},
|
|
1195
|
+
{
|
|
1196
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/live-events\/stream$/,
|
|
1197
|
+
label: "/v1/workspaces/:workspaceId/live-events/stream",
|
|
1198
|
+
},
|
|
1199
|
+
{
|
|
1200
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/interaction-events\/stream$/,
|
|
1201
|
+
label: "/v1/workspaces/:workspaceId/interaction-events/stream",
|
|
1202
|
+
},
|
|
1203
|
+
{
|
|
1204
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/attached-browsers\/[^/]+$/,
|
|
1205
|
+
label: "/v1/workspaces/:workspaceId/attached-browsers/:deviceId",
|
|
1206
|
+
},
|
|
1207
|
+
{
|
|
1208
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/attached-browsers$/,
|
|
1209
|
+
label: "/v1/workspaces/:workspaceId/attached-browsers",
|
|
1210
|
+
},
|
|
1211
|
+
{
|
|
1212
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/browser-identities\/[^/]+\/revisions$/,
|
|
1213
|
+
label: "/v1/workspaces/:workspaceId/browser-identities/:identityId/revisions",
|
|
1214
|
+
},
|
|
1215
|
+
{
|
|
1216
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/browser-identities\/[^/]+$/,
|
|
1217
|
+
label: "/v1/workspaces/:workspaceId/browser-identities/:identityId",
|
|
1218
|
+
},
|
|
1219
|
+
{
|
|
1220
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/browser-identities$/,
|
|
1221
|
+
label: "/v1/workspaces/:workspaceId/browser-identities",
|
|
1222
|
+
},
|
|
1223
|
+
{
|
|
1224
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/downloads\/[^/]+\/save$/,
|
|
1225
|
+
label:
|
|
1226
|
+
"/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/downloads/:downloadId/save",
|
|
1227
|
+
},
|
|
1228
|
+
{
|
|
1229
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/downloads\/[^/]+$/,
|
|
1230
|
+
label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/downloads/:downloadId",
|
|
1231
|
+
},
|
|
1232
|
+
{
|
|
1233
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/downloads$/,
|
|
1234
|
+
label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/downloads",
|
|
1235
|
+
},
|
|
1236
|
+
{
|
|
1237
|
+
pattern:
|
|
1238
|
+
/^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/auth-runs\/[^/]+\/external-auth\/interactive$/,
|
|
1239
|
+
label:
|
|
1240
|
+
"/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/auth-runs/:authRunId/external-auth/interactive",
|
|
1241
|
+
},
|
|
1242
|
+
{
|
|
1243
|
+
pattern:
|
|
1244
|
+
/^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/auth-runs\/[^/]+\/(external-auth|protected-fill|report|verify)$/,
|
|
1245
|
+
label: (match) =>
|
|
1246
|
+
`/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/auth-runs/:authRunId/${match[1]}`,
|
|
1247
|
+
},
|
|
1248
|
+
{
|
|
1249
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/auth-runs\/[^/]+$/,
|
|
1250
|
+
label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/auth-runs/:authRunId",
|
|
1251
|
+
},
|
|
1252
|
+
{
|
|
1253
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/auth-runs$/,
|
|
1254
|
+
label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/auth-runs",
|
|
1255
|
+
},
|
|
1256
|
+
{
|
|
1257
|
+
pattern:
|
|
1258
|
+
/^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/targets\/[^/]+\/(diagnostics|observation|select)$/,
|
|
1259
|
+
label: (match) =>
|
|
1260
|
+
`/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/targets/:targetId/${match[1]}`,
|
|
1261
|
+
},
|
|
1262
|
+
{
|
|
1263
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/targets\/[^/]+$/,
|
|
1264
|
+
label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/targets/:targetId",
|
|
1265
|
+
},
|
|
1266
|
+
{
|
|
1267
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/operations\/[^/]+$/,
|
|
1268
|
+
label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/operations/:operationId",
|
|
1269
|
+
},
|
|
1270
|
+
{
|
|
1271
|
+
pattern:
|
|
1272
|
+
/^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+\/(actions|attachments|clipboard|end|heartbeat|resume|revisions|suspend|targets)$/,
|
|
1273
|
+
label: (match) => `/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId/${match[1]}`,
|
|
1274
|
+
},
|
|
1275
|
+
{
|
|
1276
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions\/[^/]+$/,
|
|
1277
|
+
label: "/v1/workspaces/:workspaceId/browser-sessions/:browserSessionId",
|
|
1278
|
+
},
|
|
1279
|
+
{
|
|
1280
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/browser-sessions$/,
|
|
1281
|
+
label: "/v1/workspaces/:workspaceId/browser-sessions",
|
|
1282
|
+
},
|
|
1283
|
+
{
|
|
1284
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/computer-sessions\/[^/]+\/targets\/[^/]+\/observation$/,
|
|
1285
|
+
label:
|
|
1286
|
+
"/v1/workspaces/:workspaceId/computer-sessions/:computerSessionId/targets/:targetId/observation",
|
|
1287
|
+
},
|
|
1288
|
+
{
|
|
1289
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/computer-sessions\/[^/]+\/operations\/[^/]+$/,
|
|
1290
|
+
label:
|
|
1291
|
+
"/v1/workspaces/:workspaceId/computer-sessions/:computerSessionId/operations/:operationId",
|
|
1292
|
+
},
|
|
1293
|
+
{
|
|
1294
|
+
pattern:
|
|
1295
|
+
/^\/v1\/workspaces\/[^/]+\/computer-sessions\/[^/]+\/(actions|attachments|clipboard|end|heartbeat|targets)$/,
|
|
1296
|
+
label: (match) =>
|
|
1297
|
+
`/v1/workspaces/:workspaceId/computer-sessions/:computerSessionId/${match[1]}`,
|
|
1298
|
+
},
|
|
1299
|
+
{
|
|
1300
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/computer-sessions\/[^/]+$/,
|
|
1301
|
+
label: "/v1/workspaces/:workspaceId/computer-sessions/:computerSessionId",
|
|
1302
|
+
},
|
|
1303
|
+
{
|
|
1304
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/computer-sessions$/,
|
|
1305
|
+
label: "/v1/workspaces/:workspaceId/computer-sessions",
|
|
1306
|
+
},
|
|
1307
|
+
{
|
|
1308
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/network-routes\/[^/]+$/,
|
|
1309
|
+
label: "/v1/workspaces/:workspaceId/network-routes/:networkRouteId",
|
|
1310
|
+
},
|
|
1311
|
+
{
|
|
1312
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/network-routes$/,
|
|
1313
|
+
label: "/v1/workspaces/:workspaceId/network-routes",
|
|
1314
|
+
},
|
|
1315
|
+
{
|
|
1316
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/site-auth-connections\/[^/]+$/,
|
|
1317
|
+
label: "/v1/workspaces/:workspaceId/site-auth-connections/:siteAuthConnectionId",
|
|
1318
|
+
},
|
|
1319
|
+
{
|
|
1320
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/site-auth-connections$/,
|
|
1321
|
+
label: "/v1/workspaces/:workspaceId/site-auth-connections",
|
|
1322
|
+
},
|
|
1323
|
+
{
|
|
1324
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/auth-runs\/[^/]+$/,
|
|
1325
|
+
label: "/v1/workspaces/:workspaceId/auth-runs/:authRunId",
|
|
1326
|
+
},
|
|
1327
|
+
{
|
|
1328
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/auth-runs$/,
|
|
1329
|
+
label: "/v1/workspaces/:workspaceId/auth-runs",
|
|
1330
|
+
},
|
|
1331
|
+
{
|
|
1332
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/interaction-interventions\/[^/]+\/resolve$/,
|
|
1333
|
+
label: "/v1/workspaces/:workspaceId/interaction-interventions/:interventionId/resolve",
|
|
1334
|
+
},
|
|
1335
|
+
{
|
|
1336
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/interaction-interventions\/[^/]+$/,
|
|
1337
|
+
label: "/v1/workspaces/:workspaceId/interaction-interventions/:interventionId",
|
|
1338
|
+
},
|
|
1339
|
+
{
|
|
1340
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/interaction-interventions$/,
|
|
1341
|
+
label: "/v1/workspaces/:workspaceId/interaction-interventions",
|
|
1342
|
+
},
|
|
940
1343
|
{
|
|
941
1344
|
pattern: /^\/v1\/workspaces\/[^/]+\/control-events$/,
|
|
942
1345
|
label: "/v1/workspaces/:workspaceId/control-events",
|
|
@@ -945,6 +1348,23 @@ const routeLabelPatterns: Array<{ pattern: RegExp; label: string }> = [
|
|
|
945
1348
|
pattern: /^\/v1\/workspaces\/[^/]+\/inference-control$/,
|
|
946
1349
|
label: "/v1/workspaces/:workspaceId/inference-control",
|
|
947
1350
|
},
|
|
1351
|
+
{
|
|
1352
|
+
pattern:
|
|
1353
|
+
/^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/fs\/(list|list-batch|read|write|delete|move|mkdir)$/,
|
|
1354
|
+
label: "/v1/workspaces/:workspaceId/sessions/:id/fs/:operation",
|
|
1355
|
+
},
|
|
1356
|
+
{
|
|
1357
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/git\/(status|diff|read-batch|log|show)$/,
|
|
1358
|
+
label: "/v1/workspaces/:workspaceId/sessions/:id/git/:operation",
|
|
1359
|
+
},
|
|
1360
|
+
{
|
|
1361
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/terminal\/(exec|pty)$/,
|
|
1362
|
+
label: "/v1/workspaces/:workspaceId/sessions/:id/terminal/:operation",
|
|
1363
|
+
},
|
|
1364
|
+
{
|
|
1365
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/terminal\/pty\/(write|resize|close)$/,
|
|
1366
|
+
label: "/v1/workspaces/:workspaceId/sessions/:id/terminal/pty/:action",
|
|
1367
|
+
},
|
|
948
1368
|
{
|
|
949
1369
|
pattern: /^\/v1\/workspaces\/[^/]+\/sessions\/[^/]+\/events\/stream$/,
|
|
950
1370
|
label: "/v1/workspaces/:workspaceId/sessions/:id/events/stream",
|
|
@@ -1141,6 +1561,80 @@ const routeLabelPatterns: Array<{ pattern: RegExp; label: string }> = [
|
|
|
1141
1561
|
pattern: /^\/v1\/workspaces\/[^/]+\/capabilities\/[^/]+\/disable$/,
|
|
1142
1562
|
label: "/v1/workspaces/:workspaceId/capabilities/:id/disable",
|
|
1143
1563
|
},
|
|
1564
|
+
{
|
|
1565
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/preview$/,
|
|
1566
|
+
label: "/v1/workspaces/:workspaceId/integrations/preview",
|
|
1567
|
+
},
|
|
1568
|
+
{
|
|
1569
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/install$/,
|
|
1570
|
+
label: "/v1/workspaces/:workspaceId/integrations/install",
|
|
1571
|
+
},
|
|
1572
|
+
{
|
|
1573
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/definitions$/,
|
|
1574
|
+
label: "/v1/workspaces/:workspaceId/integrations/definitions",
|
|
1575
|
+
},
|
|
1576
|
+
{
|
|
1577
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/uninstall-preview$/,
|
|
1578
|
+
label:
|
|
1579
|
+
"/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/uninstall-preview",
|
|
1580
|
+
},
|
|
1581
|
+
{
|
|
1582
|
+
pattern:
|
|
1583
|
+
/^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/facets\/[^/]+\/browse$/,
|
|
1584
|
+
label:
|
|
1585
|
+
"/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets/:facetKey/browse",
|
|
1586
|
+
},
|
|
1587
|
+
{
|
|
1588
|
+
pattern:
|
|
1589
|
+
/^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/facets\/[^/]+\/source$/,
|
|
1590
|
+
label:
|
|
1591
|
+
"/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets/:facetKey/source",
|
|
1592
|
+
},
|
|
1593
|
+
{
|
|
1594
|
+
pattern:
|
|
1595
|
+
/^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/facets\/[^/]+\/pause$/,
|
|
1596
|
+
label:
|
|
1597
|
+
"/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets/:facetKey/pause",
|
|
1598
|
+
},
|
|
1599
|
+
{
|
|
1600
|
+
pattern:
|
|
1601
|
+
/^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/facets\/[^/]+\/resume$/,
|
|
1602
|
+
label:
|
|
1603
|
+
"/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets/:facetKey/resume",
|
|
1604
|
+
},
|
|
1605
|
+
{
|
|
1606
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/facets\/[^/]+$/,
|
|
1607
|
+
label:
|
|
1608
|
+
"/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets/:facetKey",
|
|
1609
|
+
},
|
|
1610
|
+
{
|
|
1611
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+\/facets$/,
|
|
1612
|
+
label: "/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey/facets",
|
|
1613
|
+
},
|
|
1614
|
+
{
|
|
1615
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/[^/]+\/instances\/[^/]+$/,
|
|
1616
|
+
label: "/v1/workspaces/:workspaceId/integrations/:capabilityId/instances/:instanceKey",
|
|
1617
|
+
},
|
|
1618
|
+
{
|
|
1619
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/integrations$/,
|
|
1620
|
+
label: "/v1/workspaces/:workspaceId/integrations",
|
|
1621
|
+
},
|
|
1622
|
+
{
|
|
1623
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/skills\/preview$/,
|
|
1624
|
+
label: "/v1/workspaces/:workspaceId/skills/preview",
|
|
1625
|
+
},
|
|
1626
|
+
{
|
|
1627
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/skills\/install$/,
|
|
1628
|
+
label: "/v1/workspaces/:workspaceId/skills/install",
|
|
1629
|
+
},
|
|
1630
|
+
{
|
|
1631
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/skills\/[^/]+\/uninstall-preview$/,
|
|
1632
|
+
label: "/v1/workspaces/:workspaceId/skills/:id/uninstall-preview",
|
|
1633
|
+
},
|
|
1634
|
+
{
|
|
1635
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/skills\/[^/]+$/,
|
|
1636
|
+
label: "/v1/workspaces/:workspaceId/skills/:id",
|
|
1637
|
+
},
|
|
1144
1638
|
{
|
|
1145
1639
|
pattern: /^\/v1\/workspaces\/[^/]+\/environments$/,
|
|
1146
1640
|
label: "/v1/workspaces/:workspaceId/environments",
|
|
@@ -1173,6 +1667,26 @@ const routeLabelPatterns: Array<{ pattern: RegExp; label: string }> = [
|
|
|
1173
1667
|
pattern: /^\/v1\/workspaces\/[^/]+\/packs\/[^/]+$/,
|
|
1174
1668
|
label: "/v1/workspaces/:workspaceId/packs/:id",
|
|
1175
1669
|
},
|
|
1670
|
+
{
|
|
1671
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/plugins\/preview$/,
|
|
1672
|
+
label: "/v1/workspaces/:workspaceId/plugins/preview",
|
|
1673
|
+
},
|
|
1674
|
+
{
|
|
1675
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/plugins$/,
|
|
1676
|
+
label: "/v1/workspaces/:workspaceId/plugins",
|
|
1677
|
+
},
|
|
1678
|
+
{
|
|
1679
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/plugins\/install$/,
|
|
1680
|
+
label: "/v1/workspaces/:workspaceId/plugins/install",
|
|
1681
|
+
},
|
|
1682
|
+
{
|
|
1683
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/plugins\/[^/]+\/uninstall-preview$/,
|
|
1684
|
+
label: "/v1/workspaces/:workspaceId/plugins/:pluginKey/uninstall-preview",
|
|
1685
|
+
},
|
|
1686
|
+
{
|
|
1687
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/plugins\/[^/]+$/,
|
|
1688
|
+
label: "/v1/workspaces/:workspaceId/plugins/:pluginKey",
|
|
1689
|
+
},
|
|
1176
1690
|
{
|
|
1177
1691
|
pattern: /^\/v1\/workspaces\/[^/]+\/social\/connections$/,
|
|
1178
1692
|
label: "/v1/workspaces/:workspaceId/social/connections",
|
|
@@ -1189,10 +1703,26 @@ const routeLabelPatterns: Array<{ pattern: RegExp; label: string }> = [
|
|
|
1189
1703
|
pattern: /^\/v1\/workspaces\/[^/]+\/connections\/oauth\/start$/,
|
|
1190
1704
|
label: "/v1/workspaces/:workspaceId/connections/oauth/start",
|
|
1191
1705
|
},
|
|
1706
|
+
{
|
|
1707
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/integrations\/oauth\/start$/,
|
|
1708
|
+
label: "/v1/workspaces/:workspaceId/integrations/oauth/start",
|
|
1709
|
+
},
|
|
1192
1710
|
{
|
|
1193
1711
|
pattern: /^\/v1\/workspaces\/[^/]+\/connections\/slack-bot\/install$/,
|
|
1194
1712
|
label: "/v1/workspaces/:workspaceId/connections/slack-bot/install",
|
|
1195
1713
|
},
|
|
1714
|
+
{
|
|
1715
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/connections\/fiken\/install$/,
|
|
1716
|
+
label: "/v1/workspaces/:workspaceId/connections/fiken/install",
|
|
1717
|
+
},
|
|
1718
|
+
{
|
|
1719
|
+
pattern: /^\/v1\/workspaces\/[^/]+\/connections\/fiken\/oauth\/start$/,
|
|
1720
|
+
label: "/v1/workspaces/:workspaceId/connections/fiken/oauth/start",
|
|
1721
|
+
},
|
|
1722
|
+
{
|
|
1723
|
+
pattern: /^\/v1\/integrations\/fiken\/callback$/,
|
|
1724
|
+
label: "/v1/integrations/fiken/callback",
|
|
1725
|
+
},
|
|
1196
1726
|
{
|
|
1197
1727
|
pattern: /^\/v1\/workspaces\/[^/]+\/connections\/[^/]+$/,
|
|
1198
1728
|
label: "/v1/workspaces/:workspaceId/connections/:connectionId",
|
|
@@ -1202,6 +1732,14 @@ const routeLabelPatterns: Array<{ pattern: RegExp; label: string }> = [
|
|
|
1202
1732
|
pattern: /^\/v1\/integrations\/oauth\/callback$/,
|
|
1203
1733
|
label: "/v1/integrations/oauth/callback",
|
|
1204
1734
|
},
|
|
1735
|
+
{
|
|
1736
|
+
pattern: /^\/v1\/integrations\/provider-oauth\/callback$/,
|
|
1737
|
+
label: "/v1/integrations/provider-oauth/callback",
|
|
1738
|
+
},
|
|
1739
|
+
{
|
|
1740
|
+
pattern: /^\/v1\/integrations\/google-drive\/callback$/,
|
|
1741
|
+
label: "/v1/integrations/google-drive/callback",
|
|
1742
|
+
},
|
|
1205
1743
|
{
|
|
1206
1744
|
pattern: /^\/v1\/integrations\/oauth\/client-metadata\.json$/,
|
|
1207
1745
|
label: "/v1/integrations/oauth/client-metadata.json",
|
|
@@ -1258,9 +1796,11 @@ const routeLabelPatterns: Array<{ pattern: RegExp; label: string }> = [
|
|
|
1258
1796
|
];
|
|
1259
1797
|
|
|
1260
1798
|
export function routeLabel(pathname: string): string {
|
|
1261
|
-
const
|
|
1262
|
-
|
|
1263
|
-
|
|
1799
|
+
for (const candidate of routeLabelPatterns) {
|
|
1800
|
+
const match = pathname.match(candidate.pattern);
|
|
1801
|
+
if (match) {
|
|
1802
|
+
return typeof candidate.label === "string" ? candidate.label : candidate.label(match);
|
|
1803
|
+
}
|
|
1264
1804
|
}
|
|
1265
1805
|
return pathname.startsWith("/v1/") ? "/v1/unknown" : "/unknown";
|
|
1266
1806
|
}
|