@superblocksteam/gateway 2.0.165-next.0 → 2.0.166-next.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/agents/resolve-orchestrator-url.d.ts +19 -1
- package/dist/agents/resolve-orchestrator-url.js +71 -20
- package/dist/agents/resolve-orchestrator-url.js.map +1 -1
- package/dist/capabilities/integration-metadata.d.ts +3 -0
- package/dist/capabilities/integration-metadata.js +34 -11
- package/dist/capabilities/integration-metadata.js.map +1 -1
- package/dist/capabilities/lifecycle.d.ts +16 -1
- package/dist/capabilities/lifecycle.js +72 -25
- package/dist/capabilities/lifecycle.js.map +1 -1
- package/dist/capabilities/query-integration.d.ts +5 -0
- package/dist/capabilities/query-integration.js +61 -18
- package/dist/capabilities/query-integration.js.map +1 -1
- package/dist/{transports/mcp → capture}/cowork-editor-url.d.ts +2 -2
- package/dist/capture/cowork-editor-url.js +12 -0
- package/dist/capture/cowork-editor-url.js.map +1 -0
- package/dist/integrations/profile-key.d.ts +50 -6
- package/dist/integrations/profile-key.js +101 -22
- package/dist/integrations/profile-key.js.map +1 -1
- package/dist/integrations/resolve-profile.d.ts +30 -0
- package/dist/integrations/resolve-profile.js +104 -0
- package/dist/integrations/resolve-profile.js.map +1 -0
- package/dist/orchestrator/client.d.ts +1 -1
- package/dist/orchestrator/client.js +1 -1
- package/dist/orchestrator/client.js.map +1 -1
- package/dist/sabs/editor-client-methods.d.ts +7 -2
- package/dist/sabs/editor-client-methods.js +10 -2
- package/dist/sabs/editor-client-methods.js.map +1 -1
- package/dist/sabs/recent-tool-runs.d.ts +1 -1
- package/dist/sabs/recent-tool-runs.js +2 -2
- package/dist/sabs/recent-tool-runs.js.map +1 -1
- package/dist/sabs/websocket-session-peer.d.ts +31 -0
- package/dist/sabs/websocket-session-peer.js +202 -35
- package/dist/sabs/websocket-session-peer.js.map +1 -1
- package/dist/server/client.d.ts +67 -15
- package/dist/server/client.js +403 -51
- package/dist/server/client.js.map +1 -1
- package/dist/telemetry/metrics.d.ts +14 -0
- package/dist/telemetry/metrics.js +25 -0
- package/dist/telemetry/metrics.js.map +1 -1
- package/dist/transports/mcp/instructions/tools/check-app-progress.js +6 -2
- package/dist/transports/mcp/instructions/tools/check-app-progress.js.map +1 -1
- package/dist/transports/mcp/instructions/tools/copy.d.ts +2 -0
- package/dist/transports/mcp/instructions/tools/copy.js +31 -1
- package/dist/transports/mcp/instructions/tools/copy.js.map +1 -1
- package/dist/transports/mcp/instructions/tools/edit-app.js +4 -1
- package/dist/transports/mcp/instructions/tools/edit-app.js.map +1 -1
- package/dist/transports/mcp/instructions/tools/get-integration-metadata.js +3 -0
- package/dist/transports/mcp/instructions/tools/get-integration-metadata.js.map +1 -1
- package/dist/transports/mcp/instructions/tools/start-app.js +4 -1
- package/dist/transports/mcp/instructions/tools/start-app.js.map +1 -1
- package/dist/transports/mcp/mount.d.ts +1 -1
- package/dist/transports/mcp/mount.js +80 -10
- package/dist/transports/mcp/mount.js.map +1 -1
- package/dist/transports/mcp/plan-approval.d.ts +29 -0
- package/dist/transports/mcp/plan-approval.js +72 -18
- package/dist/transports/mcp/plan-approval.js.map +1 -1
- package/package.json +5 -5
- package/dist/transports/mcp/cowork-editor-url.js +0 -10
- package/dist/transports/mcp/cowork-editor-url.js.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { pickOrchestratorBaseUrl } from "../agents/resolve-orchestrator-url.js";
|
|
1
|
+
import { AGENT_TYPE_ONPREMISE, pickOrchestratorBaseUrl, } from "../agents/resolve-orchestrator-url.js";
|
|
2
2
|
import { hasBuildPermission } from "../integrations/map.js";
|
|
3
|
-
import { pickEditorProfileKey } from "../integrations/profile-key.js";
|
|
4
3
|
import { isReadOnlyPostgresQuery, supportsReadOnlyPostgresQuery, } from "../integrations/read-only-postgres-query.js";
|
|
4
|
+
import { describeProfile, profileSummary, profileUnresolvedMessage, resolveProfileForApplication, } from "../integrations/resolve-profile.js";
|
|
5
5
|
import { HttpOrchestratorClient } from "../orchestrator/client.js";
|
|
6
6
|
import { sanitizeAgentFacingText } from "../sabs/agent-facing-text.js";
|
|
7
7
|
import { executeRequestToIntegrationViaOrchestrator, } from "../sabs/editor-client-methods.js";
|
|
8
|
-
import { ensurePrincipal } from "./lifecycle.js";
|
|
8
|
+
import { ensurePrincipal, resolveApplicationId, } from "./lifecycle.js";
|
|
9
9
|
const DEFAULT_QUERY_TIMEOUT_MS = 30_000;
|
|
10
10
|
const MAX_RESPONSE_CHARS = 50_000;
|
|
11
11
|
const RESPONSE_RESERVE_MS = 1_000;
|
|
@@ -14,8 +14,9 @@ function boundedText(text) {
|
|
|
14
14
|
if (text.length <= MAX_RESPONSE_CHARS) {
|
|
15
15
|
return { text, truncated: false };
|
|
16
16
|
}
|
|
17
|
+
const sliceLength = MAX_RESPONSE_CHARS - TRUNCATED_SUFFIX.length;
|
|
17
18
|
return {
|
|
18
|
-
text: `${text.slice(0,
|
|
19
|
+
text: `${text.slice(0, sliceLength)}${TRUNCATED_SUFFIX}`,
|
|
19
20
|
truncated: true,
|
|
20
21
|
};
|
|
21
22
|
}
|
|
@@ -60,19 +61,25 @@ export async function queryIntegration(context, input) {
|
|
|
60
61
|
const queryTimeoutMs = Math.max(1, context.config.hostCallCeilingMs - RESPONSE_RESERVE_MS);
|
|
61
62
|
const deadlineAtMs = Date.now() + queryTimeoutMs;
|
|
62
63
|
const beforeDeadline = (pending) => beforeQueryDeadline(pending, deadlineAtMs, context.signal);
|
|
64
|
+
let applicationId;
|
|
65
|
+
let profileResolution;
|
|
63
66
|
let label = sanitizeAgentFacingText(input.integrationId);
|
|
64
67
|
try {
|
|
65
68
|
const principal = await beforeDeadline(ensurePrincipal(context));
|
|
66
69
|
if (principal.kind !== "ok") {
|
|
67
70
|
return principal;
|
|
68
71
|
}
|
|
72
|
+
const resolved = await beforeDeadline(resolveApplicationId(context, principal.value, input.applicationId));
|
|
73
|
+
applicationId = resolved.kind === "ok" ? resolved.value : undefined;
|
|
69
74
|
const integrations = await beforeDeadline(context.server.getSupersetIntegrations({
|
|
70
75
|
apiKey: principal.value.apiKey,
|
|
76
|
+
...(applicationId && { applicationId }),
|
|
71
77
|
organizationId: principal.value.organizationId,
|
|
72
78
|
}));
|
|
73
79
|
const integration = integrations.find((candidate) => candidate.id === input.integrationId);
|
|
74
80
|
if (!integration) {
|
|
75
81
|
return {
|
|
82
|
+
...(applicationId && { applicationId }),
|
|
76
83
|
kind: "error",
|
|
77
84
|
code: "integration_not_accessible",
|
|
78
85
|
message: `Integration ${label} was not found or is not accessible.`,
|
|
@@ -83,6 +90,7 @@ export async function queryIntegration(context, input) {
|
|
|
83
90
|
label = integrationName;
|
|
84
91
|
if (!hasBuildPermission(integration)) {
|
|
85
92
|
return {
|
|
93
|
+
...(applicationId && { applicationId }),
|
|
86
94
|
kind: "error",
|
|
87
95
|
code: "integration_not_permitted",
|
|
88
96
|
message: `You do not have build permission on ${integrationName}.`,
|
|
@@ -90,6 +98,7 @@ export async function queryIntegration(context, input) {
|
|
|
90
98
|
}
|
|
91
99
|
if (!supportsReadOnlyPostgresQuery(integration.pluginId)) {
|
|
92
100
|
return {
|
|
101
|
+
...(applicationId && { applicationId }),
|
|
93
102
|
kind: "error",
|
|
94
103
|
code: "integration_query_not_supported",
|
|
95
104
|
message: `${integrationName} is not a supported PostgreSQL integration for direct read-only queries.`,
|
|
@@ -97,33 +106,63 @@ export async function queryIntegration(context, input) {
|
|
|
97
106
|
}
|
|
98
107
|
if (!(await beforeDeadline(isReadOnlyPostgresQuery(input.query)))) {
|
|
99
108
|
return {
|
|
109
|
+
...(applicationId && { applicationId }),
|
|
100
110
|
kind: "error",
|
|
101
111
|
code: "integration_query_not_read_only",
|
|
102
112
|
message: "Provide exactly one read-only SELECT, CTE, SHOW, or EXPLAIN query. Mutations, schema or session changes, row locks, and functions other than count, sum, avg, min, and max are not allowed.",
|
|
103
113
|
};
|
|
104
114
|
}
|
|
105
|
-
|
|
115
|
+
({ resolution: profileResolution } = await resolveProfileForApplication({
|
|
106
116
|
apiKey: principal.value.apiKey,
|
|
117
|
+
applicationId,
|
|
118
|
+
configuredKey: context.config.profileKey,
|
|
107
119
|
organizationId: principal.value.organizationId,
|
|
120
|
+
scope: "integration_query",
|
|
121
|
+
server: context.server,
|
|
122
|
+
wrap: beforeDeadline,
|
|
108
123
|
}));
|
|
109
|
-
const profileKey =
|
|
124
|
+
const profileKey = profileResolution.key;
|
|
110
125
|
const inventory = await beforeDeadline(context.server.getAgentInventory({
|
|
111
126
|
apiKey: principal.value.apiKey,
|
|
112
127
|
organizationId: principal.value.organizationId,
|
|
113
128
|
}));
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
129
|
+
let orchestratorUrl;
|
|
130
|
+
try {
|
|
131
|
+
orchestratorUrl = pickOrchestratorBaseUrl({
|
|
132
|
+
agentType: inventory.agentType,
|
|
133
|
+
agents: inventory.agents,
|
|
134
|
+
controlPlaneUrl: inventory.controlPlaneUrl,
|
|
135
|
+
profileKey,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
// Only on-prem agents are picked by profile tag, so only there does a
|
|
140
|
+
// missing profile explain a missing agent.
|
|
141
|
+
if (profileKey || inventory.agentType !== AGENT_TYPE_ONPREMISE) {
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
...(applicationId && { applicationId }),
|
|
146
|
+
kind: "error",
|
|
147
|
+
code: "integration_profile_unresolved",
|
|
148
|
+
message: profileUnresolvedMessage(integrationName, profileResolution),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
const scopedToken = await beforeDeadline(context.server.issueScopedToken(applicationId
|
|
152
|
+
? {
|
|
153
|
+
apiKey: principal.value.apiKey,
|
|
154
|
+
applicationId,
|
|
155
|
+
scope: "apps:update",
|
|
156
|
+
}
|
|
157
|
+
: {
|
|
158
|
+
apiKey: principal.value.apiKey,
|
|
159
|
+
integrationId: input.integrationId,
|
|
160
|
+
scope: "integrations:build",
|
|
161
|
+
}));
|
|
124
162
|
const executionTimeoutMs = Math.max(1, Math.min(DEFAULT_QUERY_TIMEOUT_MS, deadlineAtMs - Date.now()));
|
|
125
163
|
const executionContext = {
|
|
126
164
|
apiKey: principal.value.apiKey,
|
|
165
|
+
...(applicationId && { applicationId }),
|
|
127
166
|
orchestrator: new HttpOrchestratorClient(orchestratorUrl, executionTimeoutMs),
|
|
128
167
|
organizationId: principal.value.organizationId,
|
|
129
168
|
profileKey,
|
|
@@ -140,8 +179,9 @@ export async function queryIntegration(context, input) {
|
|
|
140
179
|
request: { body: input.query, usePreparedSql: true },
|
|
141
180
|
}));
|
|
142
181
|
if (result.error) {
|
|
143
|
-
const { text } = boundedText(result.error);
|
|
182
|
+
const { text } = boundedText(`Query on ${integrationName} (${describeProfile(profileResolution)}) failed: ${result.error}`);
|
|
144
183
|
return {
|
|
184
|
+
...(applicationId && { applicationId }),
|
|
145
185
|
kind: "error",
|
|
146
186
|
code: "integration_query_failed",
|
|
147
187
|
message: text,
|
|
@@ -151,9 +191,11 @@ export async function queryIntegration(context, input) {
|
|
|
151
191
|
return {
|
|
152
192
|
kind: "ok",
|
|
153
193
|
value: {
|
|
194
|
+
...(applicationId && { applicationId }),
|
|
154
195
|
integrationId: integration.id,
|
|
155
196
|
integrationName,
|
|
156
197
|
pluginId,
|
|
198
|
+
profile: profileSummary(profileResolution),
|
|
157
199
|
response: bounded.text,
|
|
158
200
|
truncated: bounded.truncated,
|
|
159
201
|
},
|
|
@@ -161,8 +203,9 @@ export async function queryIntegration(context, input) {
|
|
|
161
203
|
}
|
|
162
204
|
catch (error) {
|
|
163
205
|
const detail = sanitizeAgentFacingText(error instanceof Error ? error.message : "Unknown integration error").replaceAll("\u2014", "-");
|
|
164
|
-
const { text } = boundedText(`Could not query ${label}: ${detail}`);
|
|
206
|
+
const { text } = boundedText(`Could not query ${label}${profileResolution ? ` (${describeProfile(profileResolution)})` : ""}: ${detail}`);
|
|
165
207
|
return {
|
|
208
|
+
...(applicationId && { applicationId }),
|
|
166
209
|
kind: "error",
|
|
167
210
|
code: "integration_query_unavailable",
|
|
168
211
|
message: text,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-integration.js","sourceRoot":"","sources":["../../src/capabilities/query-integration.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"query-integration.js","sourceRoot":"","sources":["../../src/capabilities/query-integration.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,EACL,uBAAuB,EACvB,6BAA6B,GAC9B,MAAM,6CAA6C,CAAC;AACrD,OAAO,EACL,eAAe,EACf,cAAc,EACd,wBAAwB,EACxB,4BAA4B,GAE7B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EACL,0CAA0C,GAE3C,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,eAAe,EACf,oBAAoB,GAErB,MAAM,gBAAgB,CAAC;AAGxB,MAAM,wBAAwB,GAAG,MAAM,CAAC;AACxC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAClC,MAAM,gBAAgB,GAAG,eAAe,CAAC;AAmBzC,SAAS,WAAW,CAAC,IAAY;IAI/B,IAAI,IAAI,CAAC,MAAM,IAAI,kBAAkB,EAAE,CAAC;QACtC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACpC,CAAC;IACD,MAAM,WAAW,GAAG,kBAAkB,GAAG,gBAAgB,CAAC,MAAM,CAAC;IACjE,OAAO;QACL,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,GAAG,gBAAgB,EAAE;QACxD,SAAS,EAAE,IAAI;KAChB,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAmB;IAC5C,OAAO,MAAM,CAAC,MAAM,YAAY,KAAK;QACnC,CAAC,CAAC,MAAM,CAAC,MAAM;QACf,CAAC,CAAC,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;AAC5D,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,OAAmB,EACnB,YAAoB,EACpB,MAAoB;IAEpB,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IACD,MAAM,WAAW,GAAG,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC9C,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,KAAgD,CAAC;IACrD,IAAI,OAAiC,CAAC;IACtC,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAChD,KAAK,GAAG,UAAU,CAChB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC,EACtD,WAAW,CACZ,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAChD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QACD,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC3D,CAAC;YAAS,CAAC;QACT,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;YACtB,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAA0B,EAC1B,KAA4B;IAE5B,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAC7B,CAAC,EACD,OAAO,CAAC,MAAM,CAAC,iBAAiB,GAAG,mBAAmB,CACvD,CAAC;IACF,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC;IACjD,MAAM,cAAc,GAAG,CAAI,OAAmB,EAAE,EAAE,CAChD,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,IAAI,aAAiC,CAAC;IACtC,IAAI,iBAAgD,CAAC;IACrD,IAAI,KAAK,GAAG,uBAAuB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QACjE,IAAI,SAAS,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC5B,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,cAAc,CACnC,oBAAoB,CAAC,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CACpE,CAAC;QACF,aAAa,GAAG,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAEpE,MAAM,YAAY,GAAG,MAAM,cAAc,CACvC,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC;YACrC,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;YAC9B,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;YACvC,cAAc,EAAE,SAAS,CAAC,KAAK,CAAC,cAAc;SAC/C,CAAC,CACH,CAAC;QACF,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CACnC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,aAAa,CACpD,CAAC;QACF,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO;gBACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;gBACvC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,4BAA4B;gBAClC,OAAO,EAAE,eAAe,KAAK,sCAAsC;aACpE,CAAC;QACJ,CAAC;QACD,MAAM,eAAe,GAAG,uBAAuB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,QAAQ,GAAG,uBAAuB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC/D,KAAK,GAAG,eAAe,CAAC;QACxB,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,OAAO;gBACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;gBACvC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,2BAA2B;gBACjC,OAAO,EAAE,uCAAuC,eAAe,GAAG;aACnE,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,6BAA6B,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzD,OAAO;gBACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;gBACvC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,iCAAiC;gBACvC,OAAO,EAAE,GAAG,eAAe,0EAA0E;aACtG,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,CAAC,MAAM,cAAc,CAAC,uBAAuB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,OAAO;gBACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;gBACvC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,iCAAiC;gBACvC,OAAO,EACL,6LAA6L;aAChM,CAAC;QACJ,CAAC;QAED,CAAC,EAAE,UAAU,EAAE,iBAAiB,EAAE,GAAG,MAAM,4BAA4B,CAAC;YACtE,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;YAC9B,aAAa;YACb,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU;YACxC,cAAc,EAAE,SAAS,CAAC,KAAK,CAAC,cAAc;YAC9C,KAAK,EAAE,mBAAmB;YAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,IAAI,EAAE,cAAc;SACrB,CAAC,CAAC,CAAC;QACJ,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC;QACzC,MAAM,SAAS,GAAG,MAAM,cAAc,CACpC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC;YAC/B,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;YAC9B,cAAc,EAAE,SAAS,CAAC,KAAK,CAAC,cAAc;SAC/C,CAAC,CACH,CAAC;QACF,IAAI,eAAuB,CAAC;QAC5B,IAAI,CAAC;YACH,eAAe,GAAG,uBAAuB,CAAC;gBACxC,SAAS,EAAE,SAAS,CAAC,SAAS;gBAC9B,MAAM,EAAE,SAAS,CAAC,MAAM;gBACxB,eAAe,EAAE,SAAS,CAAC,eAAe;gBAC1C,UAAU;aACX,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,sEAAsE;YACtE,2CAA2C;YAC3C,IAAI,UAAU,IAAI,SAAS,CAAC,SAAS,KAAK,oBAAoB,EAAE,CAAC;gBAC/D,MAAM,KAAK,CAAC;YACd,CAAC;YACD,OAAO;gBACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;gBACvC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,gCAAgC;gBACtC,OAAO,EAAE,wBAAwB,CAAC,eAAe,EAAE,iBAAiB,CAAC;aACtE,CAAC;QACJ,CAAC;QACD,MAAM,WAAW,GAAG,MAAM,cAAc,CACtC,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAC7B,aAAa;YACX,CAAC,CAAC;gBACE,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;gBAC9B,aAAa;gBACb,KAAK,EAAE,aAAa;aACrB;YACH,CAAC,CAAC;gBACE,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;gBAC9B,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,KAAK,EAAE,oBAAoB;aAC5B,CACN,CACF,CAAC;QACF,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,CACjC,CAAC,EACD,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAC9D,CAAC;QACF,MAAM,gBAAgB,GAAgC;YACpD,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;YAC9B,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;YACvC,YAAY,EAAE,IAAI,sBAAsB,CACtC,eAAe,EACf,kBAAkB,CACnB;YACD,cAAc,EAAE,SAAS,CAAC,KAAK,CAAC,cAAc;YAC9C,UAAU;YACV,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,YAAY,EAAE,WAAW;SAC1B,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,cAAc,CACjC,0CAA0C,CAAC,gBAAgB,EAAE;YAC3D,eAAe,EAAE;gBACf,WAAW,EAAE,eAAe;gBAC5B,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,WAAW,CAAC,QAAQ;aAC3B;YACD,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE;SACrD,CAAC,CACH,CAAC;QACF,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,CAC1B,YAAY,eAAe,KAAK,eAAe,CAAC,iBAAiB,CAAC,aAAa,MAAM,CAAC,KAAK,EAAE,CAC9F,CAAC;YACF,OAAO;gBACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;gBACvC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,0BAA0B;gBAChC,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QACnD,OAAO;YACL,IAAI,EAAE,IAAI;YACV,KAAK,EAAE;gBACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;gBACvC,aAAa,EAAE,WAAW,CAAC,EAAE;gBAC7B,eAAe;gBACf,QAAQ;gBACR,OAAO,EAAE,cAAc,CAAC,iBAAiB,CAAC;gBAC1C,QAAQ,EAAE,OAAO,CAAC,IAAI;gBACtB,SAAS,EAAE,OAAO,CAAC,SAAS;aAC7B;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,uBAAuB,CACpC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B,CACrE,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC5B,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,CAC1B,mBAAmB,KAAK,GACtB,iBAAiB,CAAC,CAAC,CAAC,KAAK,eAAe,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EACnE,KAAK,MAAM,EAAE,CACd,CAAC;QACF,OAAO;YACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;YACvC,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,+BAA+B;YACrC,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The editor only renders in Cowork's host mode when the URL says so, so every
|
|
3
|
-
* editor URL handed to
|
|
4
|
-
* navigation and a publish's details page
|
|
3
|
+
* editor URL handed to a Cowork client carries the param - a build's
|
|
4
|
+
* navigation, the canvas it may open mid-build, and a publish's details page.
|
|
5
5
|
*/
|
|
6
6
|
export declare function withCoworkEditorHost(url: string): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { URL_PARAMS } from "@superblocksteam/library-shared";
|
|
2
|
+
/**
|
|
3
|
+
* The editor only renders in Cowork's host mode when the URL says so, so every
|
|
4
|
+
* editor URL handed to a Cowork client carries the param - a build's
|
|
5
|
+
* navigation, the canvas it may open mid-build, and a publish's details page.
|
|
6
|
+
*/
|
|
7
|
+
export function withCoworkEditorHost(url) {
|
|
8
|
+
const parsed = new URL(url);
|
|
9
|
+
parsed.searchParams.set(URL_PARAMS.editorHost, "cowork");
|
|
10
|
+
return parsed.toString();
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=cowork-editor-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cowork-editor-url.js","sourceRoot":"","sources":["../../src/capture/cowork-editor-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACzD,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -6,14 +6,58 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export type OrgProfileRow = {
|
|
8
8
|
allowedInEditor?: boolean;
|
|
9
|
+
/** The organization's editor default; at most one row per org sets it. */
|
|
10
|
+
defaultInEditor?: boolean;
|
|
11
|
+
id?: string;
|
|
9
12
|
key: string;
|
|
10
13
|
};
|
|
11
14
|
/**
|
|
12
|
-
*
|
|
15
|
+
* The source from which the profile key was selected.
|
|
16
|
+
* Bounded string enum suitable for OpenTelemetry metric attributes.
|
|
17
|
+
*/
|
|
18
|
+
export type ProfileKeySource = "app_default" | "none" | "operator_config" | "org_default";
|
|
19
|
+
/**
|
|
20
|
+
* The specific reason explaining why a profile key or fallback was chosen.
|
|
21
|
+
* Bounded string enum suitable for OpenTelemetry metric attributes.
|
|
22
|
+
*/
|
|
23
|
+
export type ProfileKeyReason = "app_default_missing" | "app_default_unjoinable" | "app_needs_attention" | "app_settings_unavailable" | "org_default_missing" | "operator_key_not_available" | "org_profiles_unavailable" | "resolved";
|
|
24
|
+
/**
|
|
25
|
+
* Encapsulates the resolved profile key alongside provenance and reason
|
|
26
|
+
* for telemetry and cache invalidation.
|
|
27
|
+
*/
|
|
28
|
+
export type ProfileResolution = {
|
|
29
|
+
/** Absent means: send no profile; the control plane uses the app's own default. */
|
|
30
|
+
key?: string;
|
|
31
|
+
/** Log line only, never a metric label. */
|
|
32
|
+
profileId?: string;
|
|
33
|
+
reason: ProfileKeyReason;
|
|
34
|
+
source: ProfileKeySource;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Resolves the same editor profile the browser uses for AI execution.
|
|
38
|
+
*
|
|
39
|
+
* App settings contain ids, while orchestrator requests contain keys, so the
|
|
40
|
+
* org rows are used only to join those two representations. This deliberately
|
|
41
|
+
* does not pick another allowed profile when the default cannot be joined.
|
|
42
|
+
*/
|
|
43
|
+
export declare function resolveAppEditorProfileKey(input: {
|
|
44
|
+
configuredKey: string | undefined;
|
|
45
|
+
editor: {
|
|
46
|
+
availableProfileIds: string[];
|
|
47
|
+
defaultProfileId?: string;
|
|
48
|
+
} | undefined;
|
|
49
|
+
needsAttention?: boolean;
|
|
50
|
+
orgProfiles: OrgProfileRow[];
|
|
51
|
+
}): ProfileResolution;
|
|
52
|
+
/**
|
|
53
|
+
* Resolves the organization's editor default for a request with no
|
|
54
|
+
* application in play.
|
|
13
55
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* - When the org list is unavailable, falls back to `preferred` or `staging`.
|
|
56
|
+
* A new application copies this default into its own editor settings (behind
|
|
57
|
+
* the default data tags flag), so reading metadata before an app exists sees
|
|
58
|
+
* the same profile the app will use once it does.
|
|
18
59
|
*/
|
|
19
|
-
export declare function
|
|
60
|
+
export declare function resolveOrgEditorProfileKey(input: {
|
|
61
|
+
configuredKey: string | undefined;
|
|
62
|
+
orgProfiles: OrgProfileRow[];
|
|
63
|
+
}): ProfileResolution;
|
|
@@ -4,32 +4,111 @@
|
|
|
4
4
|
* `default` — they use `dev` / `staging` / `production` — and a wrong key
|
|
5
5
|
* surfaces as orchestrator "Invalid profile specified" / HTTP 500.
|
|
6
6
|
*/
|
|
7
|
-
const AUTO_PREFERRED_KEYS = ["staging", "dev", "production"];
|
|
8
7
|
/**
|
|
9
|
-
* Resolves
|
|
8
|
+
* Resolves the same editor profile the browser uses for AI execution.
|
|
10
9
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* - When the org list is unavailable, falls back to `preferred` or `staging`.
|
|
10
|
+
* App settings contain ids, while orchestrator requests contain keys, so the
|
|
11
|
+
* org rows are used only to join those two representations. This deliberately
|
|
12
|
+
* does not pick another allowed profile when the default cannot be joined.
|
|
15
13
|
*/
|
|
16
|
-
export function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
export function resolveAppEditorProfileKey(input) {
|
|
15
|
+
if (!input.editor) {
|
|
16
|
+
return { reason: "app_settings_unavailable", source: "none" };
|
|
17
|
+
}
|
|
18
|
+
if (input.needsAttention || input.editor.availableProfileIds.length === 0) {
|
|
19
|
+
return { reason: "app_needs_attention", source: "none" };
|
|
20
|
+
}
|
|
21
|
+
if (input.orgProfiles.length === 0) {
|
|
22
|
+
return { reason: "org_profiles_unavailable", source: "none" };
|
|
23
|
+
}
|
|
24
|
+
const profilesById = new Map(input.orgProfiles.flatMap((profile) => profile.id ? [[profile.id, profile]] : []));
|
|
25
|
+
const availableProfiles = input.editor.availableProfileIds.flatMap((id) => {
|
|
26
|
+
const profile = profilesById.get(id);
|
|
27
|
+
return profile ? [profile] : [];
|
|
28
|
+
});
|
|
29
|
+
const configuredKey = input.configuredKey?.trim();
|
|
30
|
+
const hasConfiguredKey = configuredKey && configuredKey.toLowerCase() !== "default";
|
|
31
|
+
let reason = "resolved";
|
|
32
|
+
if (hasConfiguredKey) {
|
|
33
|
+
const configuredProfile = availableProfiles.find((profile) => profile.key === configuredKey);
|
|
34
|
+
if (configuredProfile) {
|
|
35
|
+
return {
|
|
36
|
+
key: configuredProfile.key,
|
|
37
|
+
profileId: configuredProfile.id,
|
|
38
|
+
reason: "resolved",
|
|
39
|
+
source: "operator_config",
|
|
40
|
+
};
|
|
31
41
|
}
|
|
42
|
+
reason = "operator_key_not_available";
|
|
43
|
+
}
|
|
44
|
+
const defaultProfileId = input.editor.defaultProfileId;
|
|
45
|
+
if (!defaultProfileId) {
|
|
46
|
+
return {
|
|
47
|
+
reason: reason === "operator_key_not_available"
|
|
48
|
+
? reason
|
|
49
|
+
: "app_default_missing",
|
|
50
|
+
source: "none",
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const defaultProfile = profilesById.get(defaultProfileId);
|
|
54
|
+
if (!defaultProfile) {
|
|
55
|
+
return {
|
|
56
|
+
profileId: defaultProfileId,
|
|
57
|
+
reason: reason === "operator_key_not_available"
|
|
58
|
+
? reason
|
|
59
|
+
: "app_default_unjoinable",
|
|
60
|
+
source: "none",
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
key: defaultProfile.key,
|
|
65
|
+
profileId: defaultProfileId,
|
|
66
|
+
reason,
|
|
67
|
+
source: "app_default",
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Resolves the organization's editor default for a request with no
|
|
72
|
+
* application in play.
|
|
73
|
+
*
|
|
74
|
+
* A new application copies this default into its own editor settings (behind
|
|
75
|
+
* the default data tags flag), so reading metadata before an app exists sees
|
|
76
|
+
* the same profile the app will use once it does.
|
|
77
|
+
*/
|
|
78
|
+
export function resolveOrgEditorProfileKey(input) {
|
|
79
|
+
if (input.orgProfiles.length === 0) {
|
|
80
|
+
return { reason: "org_profiles_unavailable", source: "none" };
|
|
81
|
+
}
|
|
82
|
+
const editorProfiles = input.orgProfiles.filter((profile) => profile.allowedInEditor !== false);
|
|
83
|
+
const configuredKey = input.configuredKey?.trim();
|
|
84
|
+
const hasConfiguredKey = configuredKey && configuredKey.toLowerCase() !== "default";
|
|
85
|
+
let reason = "resolved";
|
|
86
|
+
if (hasConfiguredKey) {
|
|
87
|
+
const configuredProfile = editorProfiles.find((profile) => profile.key === configuredKey);
|
|
88
|
+
if (configuredProfile) {
|
|
89
|
+
return {
|
|
90
|
+
key: configuredProfile.key,
|
|
91
|
+
...(configuredProfile.id && { profileId: configuredProfile.id }),
|
|
92
|
+
reason: "resolved",
|
|
93
|
+
source: "operator_config",
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
reason = "operator_key_not_available";
|
|
97
|
+
}
|
|
98
|
+
const defaultProfile = editorProfiles.find((profile) => profile.defaultInEditor === true);
|
|
99
|
+
if (!defaultProfile) {
|
|
100
|
+
return {
|
|
101
|
+
reason: reason === "operator_key_not_available"
|
|
102
|
+
? reason
|
|
103
|
+
: "org_default_missing",
|
|
104
|
+
source: "none",
|
|
105
|
+
};
|
|
32
106
|
}
|
|
33
|
-
return
|
|
107
|
+
return {
|
|
108
|
+
key: defaultProfile.key,
|
|
109
|
+
...(defaultProfile.id && { profileId: defaultProfile.id }),
|
|
110
|
+
reason,
|
|
111
|
+
source: "org_default",
|
|
112
|
+
};
|
|
34
113
|
}
|
|
35
114
|
//# sourceMappingURL=profile-key.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile-key.js","sourceRoot":"","sources":["../../src/integrations/profile-key.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"profile-key.js","sourceRoot":"","sources":["../../src/integrations/profile-key.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { SuperblocksServerClient } from "../server/client.js";
|
|
2
|
+
import { type OrgProfileRow, type ProfileResolution } from "./profile-key.js";
|
|
3
|
+
export declare function resolveProfileForApplication(input: {
|
|
4
|
+
apiKey: string;
|
|
5
|
+
applicationId?: string;
|
|
6
|
+
configuredKey: string | undefined;
|
|
7
|
+
organizationId: string;
|
|
8
|
+
scope: "held_session" | "integration_metadata" | "integration_query";
|
|
9
|
+
server: Pick<SuperblocksServerClient, "getApplicationEnvironment" | "getOrganizationProfiles">;
|
|
10
|
+
/** query_integration passes its `beforeDeadline`; metadata omits it. */
|
|
11
|
+
wrap?: <T>(pending: Promise<T>) => Promise<T>;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
profiles: OrgProfileRow[];
|
|
14
|
+
resolution: ProfileResolution;
|
|
15
|
+
}>;
|
|
16
|
+
/** What a tool result reports about the profile its data came from. */
|
|
17
|
+
export type ResolvedProfileSummary = {
|
|
18
|
+
/** Absent when no profile was sent. */
|
|
19
|
+
key?: string;
|
|
20
|
+
source: ProfileResolution["source"];
|
|
21
|
+
};
|
|
22
|
+
export declare function profileSummary(resolution: ProfileResolution): ResolvedProfileSummary;
|
|
23
|
+
/** Appended to an error so the agent can tell the user which data it tried. */
|
|
24
|
+
export declare function describeProfile(resolution: ProfileResolution): string;
|
|
25
|
+
/**
|
|
26
|
+
* On-prem agents only take requests for the profiles they are tagged with, so
|
|
27
|
+
* with no profile there is no agent to send the request to. Says why none
|
|
28
|
+
* resolved rather than reporting a missing agent.
|
|
29
|
+
*/
|
|
30
|
+
export declare function profileUnresolvedMessage(integrationName: string, resolution: ProfileResolution): string;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { recordIntegrationProfileResolution } from "../telemetry/metrics.js";
|
|
2
|
+
import { resolveAppEditorProfileKey, resolveOrgEditorProfileKey, } from "./profile-key.js";
|
|
3
|
+
function identity(pending) {
|
|
4
|
+
return pending;
|
|
5
|
+
}
|
|
6
|
+
export async function resolveProfileForApplication(input) {
|
|
7
|
+
const wrap = input.wrap ?? identity;
|
|
8
|
+
const [profiles, environment] = await Promise.all([
|
|
9
|
+
wrap(input.server
|
|
10
|
+
.getOrganizationProfiles({
|
|
11
|
+
apiKey: input.apiKey,
|
|
12
|
+
organizationId: input.organizationId,
|
|
13
|
+
})
|
|
14
|
+
.catch((error) => {
|
|
15
|
+
console.warn("gateway failed to load organization profiles", {
|
|
16
|
+
applicationId: input.applicationId,
|
|
17
|
+
message: error instanceof Error ? error.message : String(error),
|
|
18
|
+
});
|
|
19
|
+
return [];
|
|
20
|
+
})),
|
|
21
|
+
input.applicationId
|
|
22
|
+
? wrap(input.server
|
|
23
|
+
.getApplicationEnvironment({
|
|
24
|
+
apiKey: input.apiKey,
|
|
25
|
+
applicationId: input.applicationId,
|
|
26
|
+
})
|
|
27
|
+
.catch((error) => {
|
|
28
|
+
console.warn("gateway failed to load application environment", {
|
|
29
|
+
applicationId: input.applicationId,
|
|
30
|
+
message: error instanceof Error ? error.message : String(error),
|
|
31
|
+
});
|
|
32
|
+
return undefined;
|
|
33
|
+
}))
|
|
34
|
+
: undefined,
|
|
35
|
+
]);
|
|
36
|
+
// With no application there are no app settings to read, so use the
|
|
37
|
+
// organization's editor default: the profile a new app would start with.
|
|
38
|
+
// A failed app settings read is not that case and still sends no profile.
|
|
39
|
+
const resolution = input.applicationId
|
|
40
|
+
? resolveAppEditorProfileKey({
|
|
41
|
+
configuredKey: input.configuredKey,
|
|
42
|
+
editor: environment?.profiles.editor,
|
|
43
|
+
needsAttention: environment?.needsAttention?.editor,
|
|
44
|
+
orgProfiles: profiles,
|
|
45
|
+
})
|
|
46
|
+
: resolveOrgEditorProfileKey({
|
|
47
|
+
configuredKey: input.configuredKey,
|
|
48
|
+
orgProfiles: profiles,
|
|
49
|
+
});
|
|
50
|
+
recordIntegrationProfileResolution({
|
|
51
|
+
reason: resolution.reason,
|
|
52
|
+
scope: input.scope,
|
|
53
|
+
source: resolution.source,
|
|
54
|
+
});
|
|
55
|
+
console.error("gateway resolved integration profile", {
|
|
56
|
+
...(input.applicationId && { applicationId: input.applicationId }),
|
|
57
|
+
organizationId: input.organizationId,
|
|
58
|
+
...(input.configuredKey && { preferred: input.configuredKey }),
|
|
59
|
+
...(resolution.profileId && { profileId: resolution.profileId }),
|
|
60
|
+
...(resolution.key && { profileKey: resolution.key }),
|
|
61
|
+
reason: resolution.reason,
|
|
62
|
+
scope: input.scope,
|
|
63
|
+
source: resolution.source,
|
|
64
|
+
});
|
|
65
|
+
return { profiles, resolution };
|
|
66
|
+
}
|
|
67
|
+
export function profileSummary(resolution) {
|
|
68
|
+
return {
|
|
69
|
+
...(resolution.key && { key: resolution.key }),
|
|
70
|
+
source: resolution.source,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const SOURCE_LABELS = {
|
|
74
|
+
app_default: "the app's editor default",
|
|
75
|
+
none: "no profile",
|
|
76
|
+
operator_config: "the gateway configuration",
|
|
77
|
+
org_default: "the organization's editor default",
|
|
78
|
+
};
|
|
79
|
+
/** Appended to an error so the agent can tell the user which data it tried. */
|
|
80
|
+
export function describeProfile(resolution) {
|
|
81
|
+
return resolution.key
|
|
82
|
+
? `profile "${resolution.key}", from ${SOURCE_LABELS[resolution.source]}`
|
|
83
|
+
: "no profile";
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* On-prem agents only take requests for the profiles they are tagged with, so
|
|
87
|
+
* with no profile there is no agent to send the request to. Says why none
|
|
88
|
+
* resolved rather than reporting a missing agent.
|
|
89
|
+
*/
|
|
90
|
+
export function profileUnresolvedMessage(integrationName, resolution) {
|
|
91
|
+
switch (resolution.reason) {
|
|
92
|
+
case "org_default_missing":
|
|
93
|
+
return `No profile is set as the organization's default for editing, so there is no agent to send the request for ${integrationName} to. An organization admin can choose a default editing profile in the organization's profile settings.`;
|
|
94
|
+
case "org_profiles_unavailable":
|
|
95
|
+
return `The organization's profiles could not be loaded, so there is no profile to send the request for ${integrationName} with. Try again shortly.`;
|
|
96
|
+
case "operator_key_not_available":
|
|
97
|
+
return `The profile set in the gateway configuration is not available for editing and there is no default to fall back to, so there is no agent to send the request for ${integrationName} to. Remove the configured profile or choose one that is allowed in the editor.`;
|
|
98
|
+
case "app_settings_unavailable":
|
|
99
|
+
return `The app's environment settings could not be loaded, so there is no profile to send the request for ${integrationName} with. Try again shortly.`;
|
|
100
|
+
default:
|
|
101
|
+
return `The app's editor profile could not be resolved (${resolution.reason}), so there is no agent to send the request for ${integrationName} to. Check the app's environment settings.`;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=resolve-profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-profile.js","sourceRoot":"","sources":["../../src/integrations/resolve-profile.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,7 +40,7 @@ export type V2ExecuteInput = RequesterCredential & {
|
|
|
40
40
|
};
|
|
41
41
|
export type MetadataInput = RequesterCredential & {
|
|
42
42
|
integrationId: string;
|
|
43
|
-
profileKey
|
|
43
|
+
profileKey?: string;
|
|
44
44
|
scopedToken: string;
|
|
45
45
|
stepConfiguration?: Record<string, unknown>;
|
|
46
46
|
};
|
|
@@ -141,7 +141,7 @@ export class HttpOrchestratorClient {
|
|
|
141
141
|
apiKey: input.apiKey,
|
|
142
142
|
body: {
|
|
143
143
|
integration: input.integrationId,
|
|
144
|
-
profile: { name: input.profileKey },
|
|
144
|
+
...(input.profileKey ? { profile: { name: input.profileKey } } : {}),
|
|
145
145
|
stepConfiguration: input.stepConfiguration ?? {},
|
|
146
146
|
},
|
|
147
147
|
profileKey: input.profileKey,
|