@opengeni/api-router 1.4.0 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +1 -1
- package/dist/{chunk-KKEXIBQG.js → chunk-F3LQ6VWR.js} +151 -104
- package/dist/{chunk-KKEXIBQG.js.map → chunk-F3LQ6VWR.js.map} +1 -1
- package/dist/http/api-error.d.ts +14 -0
- package/dist/index.js +1 -1
- package/dist/mcp/scheduled-task-view.d.ts +4 -4
- package/dist/mcp/server.d.ts +1 -1
- package/dist/routes/sessions.d.ts +2 -0
- package/package.json +20 -20
- package/src/app.ts +17 -1
- package/src/gateway-realtime.ts +11 -7
- package/src/http/api-error.ts +36 -1
- package/src/integrations/oauth-client.ts +8 -17
- package/src/routes/sessions.ts +78 -41
- package/src/routes/workspaces.ts +12 -7
|
@@ -6612,7 +6612,11 @@ import {
|
|
|
6612
6612
|
ModelUnavailableError,
|
|
6613
6613
|
ScheduledTaskTargetAccessChange
|
|
6614
6614
|
} from "@opengeni/contracts";
|
|
6615
|
-
import {
|
|
6615
|
+
import {
|
|
6616
|
+
isDatabaseConnectionLoss,
|
|
6617
|
+
nestedPostgresSqlState as nestedPostgresSqlState4,
|
|
6618
|
+
WorkspaceControlBusyError
|
|
6619
|
+
} from "@opengeni/db";
|
|
6616
6620
|
import { HTTPException as HTTPException20 } from "hono/http-exception";
|
|
6617
6621
|
var ApiHttpError = class extends HTTPException20 {
|
|
6618
6622
|
code;
|
|
@@ -6679,6 +6683,21 @@ function databaseUnavailableHttpError(error, method) {
|
|
|
6679
6683
|
details: { code: DATABASE_UNAVAILABLE_ERROR_DETAIL_CODE }
|
|
6680
6684
|
});
|
|
6681
6685
|
}
|
|
6686
|
+
var DATABASE_CONTENTION_ERROR_DETAIL_CODE = "DATABASE_CONTENTION";
|
|
6687
|
+
function databaseContentionHttpError(error, method, options = {}) {
|
|
6688
|
+
if (error instanceof ApiHttpError) return null;
|
|
6689
|
+
if (error instanceof HTTPException20 && error.status < 500) return null;
|
|
6690
|
+
const sqlState = nestedPostgresSqlState4(error);
|
|
6691
|
+
if (sqlState !== "40P01" && sqlState !== "40001") return null;
|
|
6692
|
+
const safeMethod = method === "GET" || method === "HEAD" || method === "OPTIONS";
|
|
6693
|
+
return new ApiHttpError(503, {
|
|
6694
|
+
code: "upstream_unavailable",
|
|
6695
|
+
message: "Opengeni hit transient database contention. Retry shortly.",
|
|
6696
|
+
retryable: true,
|
|
6697
|
+
outcomeUnknown: options.outcomeUnknown ?? !safeMethod,
|
|
6698
|
+
details: { code: DATABASE_CONTENTION_ERROR_DETAIL_CODE, sqlState }
|
|
6699
|
+
});
|
|
6700
|
+
}
|
|
6682
6701
|
function agentConfigHttpError(error) {
|
|
6683
6702
|
const cause = error instanceof AgentConfigError ? error : error instanceof HTTPException20 && error.cause instanceof AgentConfigError ? error.cause : null;
|
|
6684
6703
|
if (!cause) return null;
|
|
@@ -11828,7 +11847,7 @@ import {
|
|
|
11828
11847
|
confirmLegacyInstruction,
|
|
11829
11848
|
getKnowledgeEntry,
|
|
11830
11849
|
listKnowledgeEntries,
|
|
11831
|
-
nestedPostgresSqlState as
|
|
11850
|
+
nestedPostgresSqlState as nestedPostgresSqlState5,
|
|
11832
11851
|
saveKnowledgeEntry,
|
|
11833
11852
|
saveAgentInstruction,
|
|
11834
11853
|
getAgentInstruction,
|
|
@@ -11874,7 +11893,7 @@ function registerKnowledgeEntryTools(server, deps, grant, sessionId) {
|
|
|
11874
11893
|
]
|
|
11875
11894
|
};
|
|
11876
11895
|
}
|
|
11877
|
-
const state =
|
|
11896
|
+
const state = nestedPostgresSqlState5(error);
|
|
11878
11897
|
const message = surface === "instruction" ? state === "40001" ? "This instruction changed. Read its current content and baseline, then retry the same intended edit against that exact state." : state === "23505" ? "This instruction operation ID was already used with different input. Reuse it only for an exact retry." : state === "42501" ? "The instruction change is unavailable in this task's scope or Agent learning policy. Off disables authoring, not the task. Do not ask for approval to continue." : state === "22023" || state === "23514" ? `Invalid instruction change. Read the current instruction, use append for a new rule, or edit with one localized exact oldText match to update or remove text. Agents cannot replace the complete instruction. Each supplied text and the resulting instruction must stay within ${WORKSPACE_INSTRUCTION_POLICY_CONTENT_MAX_CHARS} characters, the same limit as the human editor.` : "Workspace instructions are temporarily unavailable. Retry the same operation ID only if the prior change may have succeeded." : state === "40001" ? "This entry changed. Read its current revision and retry your correction with the current version." : state === "23505" ? "This operation ID was already used with different input. Reuse it only for an exact retry." : state === "42501" ? "The entry, reference, or write is unavailable in this task's scope and Agent learning policy. Off disables saving, not your task. Do not ask for an approval to continue." : state === "22023" || state === "23514" ? "Invalid Knowledge entry or relationship. Check the referenced IDs and revision before retrying." : "Knowledge is temporarily unavailable. Your task can continue; retry the same operation ID if saving may have succeeded.";
|
|
11879
11898
|
return {
|
|
11880
11899
|
isError: true,
|
|
@@ -12419,7 +12438,7 @@ import { HTTPException as HTTPException22 } from "hono/http-exception";
|
|
|
12419
12438
|
import {
|
|
12420
12439
|
getScheduledScopedRigVersionMetadata,
|
|
12421
12440
|
loadWorkspaceEnvironmentForRun,
|
|
12422
|
-
nestedPostgresSqlState as
|
|
12441
|
+
nestedPostgresSqlState as nestedPostgresSqlState6
|
|
12423
12442
|
} from "@opengeni/db";
|
|
12424
12443
|
async function loadSessionAttachVariableSetValues(db, settings, input) {
|
|
12425
12444
|
const { accountId, workspaceId, session, subjectId } = input;
|
|
@@ -12469,7 +12488,7 @@ async function loadSessionAttachVariableSetValues(db, settings, input) {
|
|
|
12469
12488
|
variableSetId,
|
|
12470
12489
|
source
|
|
12471
12490
|
});
|
|
12472
|
-
if (
|
|
12491
|
+
if (nestedPostgresSqlState6(error) === "42501") {
|
|
12473
12492
|
throw new ApiHttpError(403, {
|
|
12474
12493
|
code: "forbidden",
|
|
12475
12494
|
message: source === "sandbox_environment_default" ? "A default Variable Set of this session's Sandbox Environment is not available to this session." : "A Variable Set selected for this session is not available to this session.",
|
|
@@ -12483,7 +12502,7 @@ async function loadSessionAttachVariableSetValues(db, settings, input) {
|
|
|
12483
12502
|
return values;
|
|
12484
12503
|
}
|
|
12485
12504
|
function logAttachFailure(message, error, context) {
|
|
12486
|
-
const sqlState =
|
|
12505
|
+
const sqlState = nestedPostgresSqlState6(error);
|
|
12487
12506
|
console.warn(`[session-attach] ${message}`, {
|
|
12488
12507
|
...context,
|
|
12489
12508
|
...sqlState ? { sqlState } : {},
|
|
@@ -16907,7 +16926,10 @@ import {
|
|
|
16907
16926
|
} from "@opengeni/db/organization-integration-policy";
|
|
16908
16927
|
import { Client as Client2 } from "@modelcontextprotocol/sdk/client/index.js";
|
|
16909
16928
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
16910
|
-
import {
|
|
16929
|
+
import {
|
|
16930
|
+
findIntegrationsOauthClient,
|
|
16931
|
+
parseIntegrationsOauthClientsJson
|
|
16932
|
+
} from "@opengeni/config";
|
|
16911
16933
|
import {
|
|
16912
16934
|
OAuthStartResponse,
|
|
16913
16935
|
selectCanonicalPersonalSlackConnection
|
|
@@ -18513,7 +18535,6 @@ function operatorClientForAs(settings, as) {
|
|
|
18513
18535
|
};
|
|
18514
18536
|
}
|
|
18515
18537
|
function operatorClientEntryFor(settings, candidates) {
|
|
18516
|
-
const normalizedCandidates = new Set(candidates.map(normalizedIssuerKey));
|
|
18517
18538
|
const candidateOrigins = candidates.flatMap((candidate) => {
|
|
18518
18539
|
try {
|
|
18519
18540
|
return [new URL(candidate).origin];
|
|
@@ -18530,22 +18551,10 @@ function operatorClientEntryFor(settings, candidates) {
|
|
|
18530
18551
|
return resolved;
|
|
18531
18552
|
}
|
|
18532
18553
|
}
|
|
18533
|
-
|
|
18534
|
-
|
|
18535
|
-
candidates
|
|
18554
|
+
return findIntegrationsOauthClient(
|
|
18555
|
+
parseIntegrationsOauthClientsJson(settings.integrationsOauthClientsJson),
|
|
18556
|
+
candidates
|
|
18536
18557
|
);
|
|
18537
|
-
for (const key of exactKeys) {
|
|
18538
|
-
const entry2 = configured2[key];
|
|
18539
|
-
if (entry2) {
|
|
18540
|
-
return entry2;
|
|
18541
|
-
}
|
|
18542
|
-
}
|
|
18543
|
-
for (const [key, entry2] of Object.entries(configured2)) {
|
|
18544
|
-
if (normalizedCandidates.has(normalizedIssuerKey(key))) {
|
|
18545
|
-
return entry2;
|
|
18546
|
-
}
|
|
18547
|
-
}
|
|
18548
|
-
return null;
|
|
18549
18558
|
}
|
|
18550
18559
|
function gmailOAuthClientConfigured(settings) {
|
|
18551
18560
|
const entry2 = operatorClientEntryFor(settings, ["https://accounts.google.com"]);
|
|
@@ -74277,7 +74286,7 @@ import {
|
|
|
74277
74286
|
getOrganizationIntegrationPolicy,
|
|
74278
74287
|
updateOrganizationIntegrationPolicy
|
|
74279
74288
|
} from "@opengeni/db/organization-integration-policy";
|
|
74280
|
-
import { nestedPostgresSqlState as
|
|
74289
|
+
import { nestedPostgresSqlState as nestedPostgresSqlState7 } from "@opengeni/db";
|
|
74281
74290
|
import { HTTPException as HTTPException46 } from "hono/http-exception";
|
|
74282
74291
|
import { z as z32 } from "zod";
|
|
74283
74292
|
async function authorizeOrganizationIntegrationAdministration(context, deps, accountId, mutation) {
|
|
@@ -74306,7 +74315,7 @@ async function policyResponse(readOrWrite) {
|
|
|
74306
74315
|
return await readOrWrite();
|
|
74307
74316
|
} catch (error) {
|
|
74308
74317
|
if (error instanceof HTTPException46) throw error;
|
|
74309
|
-
const state =
|
|
74318
|
+
const state = nestedPostgresSqlState7(error);
|
|
74310
74319
|
if (state === "42501") {
|
|
74311
74320
|
throw new HTTPException46(403, { message: "Organization administration required" });
|
|
74312
74321
|
}
|
|
@@ -81229,7 +81238,7 @@ import {
|
|
|
81229
81238
|
listAgentLearningOverrides,
|
|
81230
81239
|
listKnowledgeEntryHistory,
|
|
81231
81240
|
listKnowledgeReviewBatches,
|
|
81232
|
-
nestedPostgresSqlState as
|
|
81241
|
+
nestedPostgresSqlState as nestedPostgresSqlState8,
|
|
81233
81242
|
restoreKnowledgeEntry,
|
|
81234
81243
|
reviewKnowledgeEntry,
|
|
81235
81244
|
saveAgentLearningSettings,
|
|
@@ -81283,7 +81292,7 @@ function knowledgeHttpError(error) {
|
|
|
81283
81292
|
throw new HTTPException57(422, {
|
|
81284
81293
|
message: error.issues[0]?.message ?? "Invalid Knowledge request"
|
|
81285
81294
|
});
|
|
81286
|
-
const state =
|
|
81295
|
+
const state = nestedPostgresSqlState8(error);
|
|
81287
81296
|
if (state === "40001" || state === "23505")
|
|
81288
81297
|
throw new HTTPException57(409, { message: "This item changed. Refresh it and try again." });
|
|
81289
81298
|
if (state === "42501")
|
|
@@ -95559,7 +95568,7 @@ import {
|
|
|
95559
95568
|
getPrReviewAppRegistrationSecret,
|
|
95560
95569
|
listPrReviewAppRegistrations as listPrReviewAppRegistrations3,
|
|
95561
95570
|
listPrReviewRepositoryBindings as listPrReviewRepositoryBindings2,
|
|
95562
|
-
nestedPostgresSqlState as
|
|
95571
|
+
nestedPostgresSqlState as nestedPostgresSqlState10,
|
|
95563
95572
|
recordAuditEvent as recordAuditEvent12,
|
|
95564
95573
|
updatePrReviewAppRegistration,
|
|
95565
95574
|
updatePrReviewRepositoryBinding
|
|
@@ -95775,7 +95784,7 @@ import {
|
|
|
95775
95784
|
getAutomationSourceSecret as getAutomationSourceSecret2,
|
|
95776
95785
|
listPrReviewAppRegistrations as listPrReviewAppRegistrations2,
|
|
95777
95786
|
listPrReviewRepositoryBindings,
|
|
95778
|
-
nestedPostgresSqlState as
|
|
95787
|
+
nestedPostgresSqlState as nestedPostgresSqlState9,
|
|
95779
95788
|
PrReviewDispatchAuthorityError,
|
|
95780
95789
|
recordAuditEvent as recordAuditEvent11,
|
|
95781
95790
|
resolveManagedGitHubPrReviewRoute,
|
|
@@ -96816,7 +96825,7 @@ function registerPrReviewGitHubRoutes(app, deps) {
|
|
|
96816
96825
|
if (error instanceof PrReviewDispatchAuthorityError) {
|
|
96817
96826
|
throw new HTTPException76(409, { message: error.message });
|
|
96818
96827
|
}
|
|
96819
|
-
if (
|
|
96828
|
+
if (nestedPostgresSqlState9(error) === "23505") {
|
|
96820
96829
|
throw new HTTPException76(409, {
|
|
96821
96830
|
message: "One of these repositories is already connected to Opengeni Lens in another workspace"
|
|
96822
96831
|
});
|
|
@@ -97561,7 +97570,7 @@ async function mapPrReviewUniqueConflict(operation, message) {
|
|
|
97561
97570
|
try {
|
|
97562
97571
|
return await operation;
|
|
97563
97572
|
} catch (error) {
|
|
97564
|
-
if (
|
|
97573
|
+
if (nestedPostgresSqlState10(error) === "23505") {
|
|
97565
97574
|
throw new HTTPException77(409, { message });
|
|
97566
97575
|
}
|
|
97567
97576
|
throw error;
|
|
@@ -100676,7 +100685,7 @@ import { searchSessionMessagesForSubject, SessionMessageSearchCursorError } from
|
|
|
100676
100685
|
import { listSessionEventSlices } from "@opengeni/db/session-event-slices";
|
|
100677
100686
|
import * as sessionPreviewSchema from "@opengeni/db/schema";
|
|
100678
100687
|
import { SessionMessageSearchRequest } from "@opengeni/contracts";
|
|
100679
|
-
import { scheduledSessionIds } from "@opengeni/db";
|
|
100688
|
+
import { requireWorkspace as requireWorkspace3, scheduledSessionIds } from "@opengeni/db";
|
|
100680
100689
|
import { isVerifiedDelegatedHumanAuthorization as isVerifiedDelegatedHumanAuthorization4, withSiteSessionOrigin as withSiteSessionOrigin3 } from "@opengeni/core";
|
|
100681
100690
|
import { freezeSessionRealtimeConnectionAccounts } from "@opengeni/core";
|
|
100682
100691
|
import {
|
|
@@ -100922,6 +100931,7 @@ async function createGatewayRealtimeConnectionSecret(input) {
|
|
|
100922
100931
|
getSessionRealtimeContinuityEntries3(input.db, input.workspaceId, input.sessionId),
|
|
100923
100932
|
mintGatewayClientSecret({
|
|
100924
100933
|
apiKey,
|
|
100934
|
+
source: resolved.source,
|
|
100925
100935
|
upstreamModelId: resolved.upstreamModelId,
|
|
100926
100936
|
fetchImpl: input.fetchImpl ?? fetch
|
|
100927
100937
|
})
|
|
@@ -100950,13 +100960,14 @@ async function mintGatewayClientSecret(input) {
|
|
|
100950
100960
|
} catch {
|
|
100951
100961
|
throw new GatewayRealtimeBrokerError(
|
|
100952
100962
|
"provider_error",
|
|
100953
|
-
"
|
|
100963
|
+
"The voice provider could not be reached. Try again."
|
|
100954
100964
|
);
|
|
100955
100965
|
}
|
|
100956
100966
|
if (!response.ok) {
|
|
100967
|
+
const rejected = response.status === 401 || response.status === 403;
|
|
100957
100968
|
throw new GatewayRealtimeBrokerError(
|
|
100958
|
-
|
|
100959
|
-
|
|
100969
|
+
rejected ? "credential_unavailable" : "provider_error",
|
|
100970
|
+
rejected ? input.source === "managed" ? "Opengeni voice is temporarily unavailable. Try another voice model." : "Your AI Gateway key was rejected. Update it in workspace settings." : "The voice provider could not start a call. Try again.",
|
|
100960
100971
|
response.status
|
|
100961
100972
|
);
|
|
100962
100973
|
}
|
|
@@ -102321,18 +102332,26 @@ function registerSessionRoutes(app, deps) {
|
|
|
102321
102332
|
if (!session) {
|
|
102322
102333
|
throw new HTTPException88(404, { message: "session not found" });
|
|
102323
102334
|
}
|
|
102324
|
-
const activity = await
|
|
102325
|
-
|
|
102326
|
-
|
|
102327
|
-
|
|
102328
|
-
|
|
102329
|
-
|
|
102335
|
+
const [activity, scheduleTargets, policy] = await Promise.all([
|
|
102336
|
+
backgroundCommandActivityForSessions(db, {
|
|
102337
|
+
accountId: grant.accountId,
|
|
102338
|
+
workspaceId,
|
|
102339
|
+
sessionIds: [sessionId]
|
|
102340
|
+
}),
|
|
102341
|
+
hasPermission23(grant.permissions, "scheduled_tasks:run") && hasPermission23(grant.permissions, "sessions:control") ? scheduledSessionIds(db, workspaceId, [sessionId]) : Promise.resolve(/* @__PURE__ */ new Set()),
|
|
102342
|
+
loadEffectivePolicyContext(deps, workspaceId, grant.subjectId, [session])
|
|
102343
|
+
]);
|
|
102330
102344
|
return c.json(
|
|
102331
|
-
|
|
102332
|
-
|
|
102333
|
-
|
|
102334
|
-
|
|
102335
|
-
|
|
102345
|
+
sessionWithEffectiveToolPolicy2(
|
|
102346
|
+
{
|
|
102347
|
+
...session,
|
|
102348
|
+
hasSchedules: scheduleTargets.has(sessionId),
|
|
102349
|
+
...activity.get(sessionId) ? { backgroundCommandActivity: activity.get(sessionId) } : {}
|
|
102350
|
+
},
|
|
102351
|
+
policy.workspaceServerIds,
|
|
102352
|
+
policy.workspaceDefaultServerIds,
|
|
102353
|
+
policy.effectiveToolsContext
|
|
102354
|
+
)
|
|
102336
102355
|
);
|
|
102337
102356
|
});
|
|
102338
102357
|
app.get("/v1/workspaces/:workspaceId/sessions/:sessionId/model-context", async (c) => {
|
|
@@ -103146,23 +103165,31 @@ function registerSessionRoutes(app, deps) {
|
|
|
103146
103165
|
});
|
|
103147
103166
|
}
|
|
103148
103167
|
try {
|
|
103149
|
-
const result = await withWorkspaceSessionActivityRls(
|
|
103150
|
-
|
|
103151
|
-
|
|
103152
|
-
|
|
103153
|
-
|
|
103154
|
-
|
|
103155
|
-
|
|
103156
|
-
|
|
103157
|
-
|
|
103158
|
-
|
|
103159
|
-
|
|
103160
|
-
|
|
103161
|
-
|
|
103162
|
-
|
|
103163
|
-
|
|
103164
|
-
|
|
103165
|
-
|
|
103168
|
+
const result = await withWorkspaceSessionActivityRls(
|
|
103169
|
+
db,
|
|
103170
|
+
workspaceId,
|
|
103171
|
+
async (scopedDb) => {
|
|
103172
|
+
await beforeCommit?.(scopedDb);
|
|
103173
|
+
return syncSessionRealtimeLedgerInTransaction(
|
|
103174
|
+
scopedDb,
|
|
103175
|
+
{
|
|
103176
|
+
workspaceId,
|
|
103177
|
+
sessionId,
|
|
103178
|
+
realtimeId,
|
|
103179
|
+
ownerSubjectId: grant.subjectId,
|
|
103180
|
+
...parsed.data,
|
|
103181
|
+
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs()
|
|
103182
|
+
},
|
|
103183
|
+
captureLinked ? {
|
|
103184
|
+
afterDelegationAdmission: async ({ turnId }) => captureLinked(scopedDb, sessionId, turnId)
|
|
103185
|
+
} : {}
|
|
103186
|
+
);
|
|
103187
|
+
},
|
|
103188
|
+
void 0,
|
|
103189
|
+
// External reauthorization takes the organization-membership lock,
|
|
103190
|
+
// which precedes the tenancy fence and the canonical session prefix.
|
|
103191
|
+
Boolean(beforeCommit)
|
|
103192
|
+
);
|
|
103166
103193
|
await publishRealtimeMutation(grant.accountId, workspaceId, sessionId, result);
|
|
103167
103194
|
c.header("cache-control", "private, no-store");
|
|
103168
103195
|
return c.json({ accepted: result.accepted, outbound: result.outbound });
|
|
@@ -105806,11 +105833,16 @@ function codexRealtimeHttpFailure(error) {
|
|
|
105806
105833
|
return { status: 409, code: "conflict", retryable: false };
|
|
105807
105834
|
}
|
|
105808
105835
|
}
|
|
105836
|
+
var SESSION_REALTIME_USER_MESSAGES = {
|
|
105837
|
+
REALTIME_ACTIVE: "Voice is already on for this session in another tab or window. End it there, or try again in a minute.",
|
|
105838
|
+
CONTROL_NOT_ACTIVE: "Resume this session to start voice.",
|
|
105839
|
+
SESSION_CANCELLED: "This session was cancelled, so voice can't start."
|
|
105840
|
+
};
|
|
105809
105841
|
function sessionRealtimeHttpError(error) {
|
|
105810
105842
|
if (error instanceof HTTPException88) return error;
|
|
105811
105843
|
if (error instanceof SessionRealtimeConflictError) {
|
|
105812
105844
|
return new HTTPException88(error.code === "REALTIME_NOT_FOUND" ? 404 : 409, {
|
|
105813
|
-
message: error.message,
|
|
105845
|
+
message: SESSION_REALTIME_USER_MESSAGES[error.code] ?? error.message,
|
|
105814
105846
|
cause: error
|
|
105815
105847
|
});
|
|
105816
105848
|
}
|
|
@@ -106588,9 +106620,17 @@ function commandConflictResponse(c, error) {
|
|
|
106588
106620
|
throw error;
|
|
106589
106621
|
}
|
|
106590
106622
|
async function loadEffectivePolicyContext(deps, workspaceId, subjectId, sessions) {
|
|
106623
|
+
const workspaceRead = requireWorkspace3(deps.db, workspaceId);
|
|
106624
|
+
void workspaceRead.catch(() => void 0);
|
|
106591
106625
|
const [policy, effectiveToolsContext] = await Promise.all([
|
|
106592
|
-
workspaceSessionToolPolicyContext(
|
|
106593
|
-
|
|
106626
|
+
workspaceSessionToolPolicyContext(
|
|
106627
|
+
deps.db,
|
|
106628
|
+
workspaceId,
|
|
106629
|
+
deps.settings,
|
|
106630
|
+
subjectId,
|
|
106631
|
+
workspaceRead
|
|
106632
|
+
),
|
|
106633
|
+
workspaceSessionEffectiveToolsContext2(deps, workspaceId, subjectId, sessions, workspaceRead)
|
|
106594
106634
|
]);
|
|
106595
106635
|
return { ...policy, effectiveToolsContext };
|
|
106596
106636
|
}
|
|
@@ -107134,9 +107174,9 @@ import {
|
|
|
107134
107174
|
replayWorkspaceGatewayCustomModelCreate,
|
|
107135
107175
|
replayWorkspaceOpenRouterCustomModelCreate,
|
|
107136
107176
|
listWorkspacesForSubject as listWorkspacesForSubject2,
|
|
107137
|
-
nestedPostgresSqlState as
|
|
107177
|
+
nestedPostgresSqlState as nestedPostgresSqlState12,
|
|
107138
107178
|
removeWorkspaceMember,
|
|
107139
|
-
requireWorkspace as
|
|
107179
|
+
requireWorkspace as requireWorkspace4,
|
|
107140
107180
|
updateWorkspaceSettings,
|
|
107141
107181
|
getRig,
|
|
107142
107182
|
setWorkspaceDefaultRig,
|
|
@@ -107185,7 +107225,7 @@ import {
|
|
|
107185
107225
|
} from "@opengeni/core";
|
|
107186
107226
|
|
|
107187
107227
|
// src/workspace-deletion.ts
|
|
107188
|
-
import { deleteWorkspaceIfQuiescent, nestedPostgresSqlState as
|
|
107228
|
+
import { deleteWorkspaceIfQuiescent, nestedPostgresSqlState as nestedPostgresSqlState11 } from "@opengeni/db";
|
|
107189
107229
|
import { HTTPException as HTTPException91 } from "hono/http-exception";
|
|
107190
107230
|
|
|
107191
107231
|
// src/workspace-delete-observability.ts
|
|
@@ -107275,7 +107315,7 @@ async function deleteWorkspaceForRequest(deps, input) {
|
|
|
107275
107315
|
...observer ? { observer } : {}
|
|
107276
107316
|
});
|
|
107277
107317
|
} catch (error) {
|
|
107278
|
-
const state =
|
|
107318
|
+
const state = nestedPostgresSqlState11(error);
|
|
107279
107319
|
if (state === "42501") {
|
|
107280
107320
|
throw new HTTPException91(403, { message: "organization administration is not authorized" });
|
|
107281
107321
|
}
|
|
@@ -107429,7 +107469,7 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
107429
107469
|
];
|
|
107430
107470
|
if (readableWorkspaceIds.length > 0) {
|
|
107431
107471
|
const workspaces = await Promise.all(
|
|
107432
|
-
readableWorkspaceIds.map((workspaceId) =>
|
|
107472
|
+
readableWorkspaceIds.map((workspaceId) => requireWorkspace4(deps.db, workspaceId))
|
|
107433
107473
|
);
|
|
107434
107474
|
return c.json(workspaces.map((workspace) => Workspace.parse(workspace)));
|
|
107435
107475
|
}
|
|
@@ -107546,7 +107586,7 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
107546
107586
|
app.get("/v1/workspaces/:workspaceId", async (c) => {
|
|
107547
107587
|
const workspaceId = c.req.param("workspaceId");
|
|
107548
107588
|
await requireAccessGrant39(c, deps, workspaceId, "workspace:read");
|
|
107549
|
-
return c.json(Workspace.parse(await
|
|
107589
|
+
return c.json(Workspace.parse(await requireWorkspace4(deps.db, workspaceId)));
|
|
107550
107590
|
});
|
|
107551
107591
|
app.patch("/v1/workspaces/:workspaceId", async (c) => {
|
|
107552
107592
|
const workspaceId = c.req.param("workspaceId");
|
|
@@ -107608,14 +107648,14 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
107608
107648
|
deps.db,
|
|
107609
107649
|
workspaceId,
|
|
107610
107650
|
parsed.data,
|
|
107611
|
-
{ requireWorkspace:
|
|
107651
|
+
{ requireWorkspace: requireWorkspace4, updateWorkspaceSettings },
|
|
107612
107652
|
{
|
|
107613
107653
|
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs2()
|
|
107614
107654
|
}
|
|
107615
107655
|
);
|
|
107616
107656
|
return c.json(Workspace.parse(workspace));
|
|
107617
107657
|
} catch (error) {
|
|
107618
|
-
if (
|
|
107658
|
+
if (nestedPostgresSqlState12(error) === "0A000") {
|
|
107619
107659
|
throw new HTTPException92(409, {
|
|
107620
107660
|
message: "Memory settings moved to Settings > Agent learning. Refresh the app to change them."
|
|
107621
107661
|
});
|
|
@@ -107811,7 +107851,7 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
107811
107851
|
if (error instanceof WorkspaceGatewayCustomModelLimitError || error instanceof WorkspaceGatewayCustomModelHistoryLimitError) {
|
|
107812
107852
|
throw new HTTPException92(422, { message: error.message });
|
|
107813
107853
|
}
|
|
107814
|
-
if (
|
|
107854
|
+
if (nestedPostgresSqlState12(error) === "23505") {
|
|
107815
107855
|
throw new HTTPException92(422, {
|
|
107816
107856
|
message: "Gateway custom model already exists"
|
|
107817
107857
|
});
|
|
@@ -107940,7 +107980,7 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
107940
107980
|
if (error instanceof WorkspaceOpenRouterCustomModelLimitError || error instanceof WorkspaceOpenRouterCustomModelHistoryLimitError) {
|
|
107941
107981
|
throw new HTTPException92(422, { message: error.message });
|
|
107942
107982
|
}
|
|
107943
|
-
if (
|
|
107983
|
+
if (nestedPostgresSqlState12(error) === "23505") {
|
|
107944
107984
|
throw new HTTPException92(422, {
|
|
107945
107985
|
message: "OpenRouter custom model already exists"
|
|
107946
107986
|
});
|
|
@@ -108020,17 +108060,18 @@ function registerWorkspaceRoutes(app, deps) {
|
|
|
108020
108060
|
}).filter(
|
|
108021
108061
|
(model, _index, offered) => offered.some((candidate) => candidate.id === AZURE_LIVE_MODEL_ID) ? model.id === AZURE_LIVE_MODEL_ID : true
|
|
108022
108062
|
);
|
|
108023
|
-
const
|
|
108063
|
+
const creditStanding = managedCandidates.length > 0 ? await createRealtimeVoiceBilling2({
|
|
108024
108064
|
db: deps.db,
|
|
108025
108065
|
settings: deps.settings
|
|
108026
|
-
}).
|
|
108066
|
+
}).creditStanding(grant.accountId) : "none";
|
|
108067
|
+
const hasCredits = creditStanding === "spendable";
|
|
108027
108068
|
const models = [
|
|
108028
108069
|
...managedCandidates.map((model, index) => ({
|
|
108029
108070
|
...model,
|
|
108030
108071
|
provider: "OpenGeni",
|
|
108031
108072
|
...hasCredits ? { available: true, unavailableReason: null, unavailableCode: null } : {
|
|
108032
108073
|
available: false,
|
|
108033
|
-
unavailableReason: "Add Opengeni credits to use live voice",
|
|
108074
|
+
unavailableReason: creditStanding === "promotional_only" ? "Promotional credits don't cover live voice. Add credits to use it." : "Add Opengeni credits to use live voice",
|
|
108034
108075
|
unavailableCode: "insufficient_credits"
|
|
108035
108076
|
},
|
|
108036
108077
|
recommended: index === 0
|
|
@@ -108378,7 +108419,7 @@ function rethrowWorkspaceMemberCandidateError(error) {
|
|
|
108378
108419
|
message: "the workspace must keep at least one administrator"
|
|
108379
108420
|
});
|
|
108380
108421
|
}
|
|
108381
|
-
const sqlState =
|
|
108422
|
+
const sqlState = nestedPostgresSqlState12(error);
|
|
108382
108423
|
if (sqlState === "P0002") {
|
|
108383
108424
|
throw new HTTPException92(404, { message: "workspace not found" });
|
|
108384
108425
|
}
|
|
@@ -108443,7 +108484,7 @@ import {
|
|
|
108443
108484
|
getWorkspace as getWorkspace6,
|
|
108444
108485
|
getWorkspaceUsage,
|
|
108445
108486
|
grantWorkspaceCredits,
|
|
108446
|
-
nestedPostgresSqlState as
|
|
108487
|
+
nestedPostgresSqlState as nestedPostgresSqlState13,
|
|
108447
108488
|
setMemberAllowance,
|
|
108448
108489
|
setWorkspaceAllowance,
|
|
108449
108490
|
withAccountRls as withAccountRls3,
|
|
@@ -108578,7 +108619,7 @@ async function lifecycle2(operation) {
|
|
|
108578
108619
|
} catch (error) {
|
|
108579
108620
|
if (error instanceof UsageAllowanceVersionConflictError)
|
|
108580
108621
|
throw new HTTPException93(409, { message: error.message });
|
|
108581
|
-
const state =
|
|
108622
|
+
const state = nestedPostgresSqlState13(error);
|
|
108582
108623
|
if (state === "40001" || state === "23505")
|
|
108583
108624
|
throw new HTTPException93(409, { message: "Allowance version or operation conflicts" });
|
|
108584
108625
|
if (state === "42501")
|
|
@@ -110329,7 +110370,7 @@ import {
|
|
|
110329
110370
|
} from "@opengeni/core";
|
|
110330
110371
|
import {
|
|
110331
110372
|
availableSlackBotConnectionMetadata as availableSlackBotConnectionMetadata2,
|
|
110332
|
-
nestedPostgresSqlState as
|
|
110373
|
+
nestedPostgresSqlState as nestedPostgresSqlState14,
|
|
110333
110374
|
readOrganizationSlackBotAccess,
|
|
110334
110375
|
setOrganizationSlackBotAccess,
|
|
110335
110376
|
sharedOrganizationSlackBots as sharedOrganizationSlackBots2
|
|
@@ -110359,7 +110400,7 @@ function registerSlackBotAccessRoutes(app, deps) {
|
|
|
110359
110400
|
)
|
|
110360
110401
|
);
|
|
110361
110402
|
} catch (error) {
|
|
110362
|
-
if (
|
|
110403
|
+
if (nestedPostgresSqlState14(error) === "42501")
|
|
110363
110404
|
throw new HTTPException99(404, { message: "Local bot installation unavailable" });
|
|
110364
110405
|
throw error;
|
|
110365
110406
|
}
|
|
@@ -110413,7 +110454,7 @@ function registerSlackBotAccessRoutes(app, deps) {
|
|
|
110413
110454
|
return context.json(OpenGeniSlackBotOrganizationAccess.parse(result));
|
|
110414
110455
|
} catch (error) {
|
|
110415
110456
|
if (error instanceof HTTPException99) throw error;
|
|
110416
|
-
if (
|
|
110457
|
+
if (nestedPostgresSqlState14(error) === "42501")
|
|
110417
110458
|
throw new HTTPException99(403, {
|
|
110418
110459
|
message: "Organization administrator and a verified local bot installation required"
|
|
110419
110460
|
});
|
|
@@ -110610,7 +110651,7 @@ import {
|
|
|
110610
110651
|
getWorkspaceArtifact as getWorkspaceArtifact3,
|
|
110611
110652
|
getWorkspaceArtifactContentRef as getWorkspaceArtifactContentRef3,
|
|
110612
110653
|
listWorkspaceArtifacts as listWorkspaceArtifacts2,
|
|
110613
|
-
nestedPostgresSqlState as
|
|
110654
|
+
nestedPostgresSqlState as nestedPostgresSqlState15,
|
|
110614
110655
|
publishWorkspaceArtifactVersion as publishWorkspaceArtifactVersion2,
|
|
110615
110656
|
rollbackWorkspaceArtifact as rollbackWorkspaceArtifact2,
|
|
110616
110657
|
setWorkspaceArtifactStatus as setWorkspaceArtifactStatus2,
|
|
@@ -110657,7 +110698,7 @@ function workspaceArtifactErrorResponse(context, error) {
|
|
|
110657
110698
|
422
|
|
110658
110699
|
);
|
|
110659
110700
|
}
|
|
110660
|
-
if (
|
|
110701
|
+
if (nestedPostgresSqlState15(error) === "23505") {
|
|
110661
110702
|
return context.json(
|
|
110662
110703
|
{
|
|
110663
110704
|
code: "WORKSPACE_ARTIFACT_CONFLICT",
|
|
@@ -111041,7 +111082,7 @@ import {
|
|
|
111041
111082
|
getGeneratedImageArtifact as getGeneratedImageArtifact2,
|
|
111042
111083
|
getSessionAuthorityProjection as getSessionAuthorityProjection3,
|
|
111043
111084
|
listArtifactCatalogCandidates,
|
|
111044
|
-
nestedPostgresSqlState as
|
|
111085
|
+
nestedPostgresSqlState as nestedPostgresSqlState16,
|
|
111045
111086
|
updateArtifactPin,
|
|
111046
111087
|
withSessionRlsActorContext as withSessionRlsActorContext9
|
|
111047
111088
|
} from "@opengeni/db";
|
|
@@ -111176,7 +111217,7 @@ function registerArtifactCatalogRoutes(app, deps) {
|
|
|
111176
111217
|
}
|
|
111177
111218
|
);
|
|
111178
111219
|
} catch (error) {
|
|
111179
|
-
if (
|
|
111220
|
+
if (nestedPostgresSqlState16(error) === "42501")
|
|
111180
111221
|
throw new HTTPException103(404, { message: "Artifact not found" });
|
|
111181
111222
|
throw error;
|
|
111182
111223
|
}
|
|
@@ -114896,11 +114937,11 @@ import {
|
|
|
114896
114937
|
getOrganizationPrivateSessionSettings,
|
|
114897
114938
|
getSelfOrganizationInvitation,
|
|
114898
114939
|
getOrganizationRetentionPolicy,
|
|
114899
|
-
requireWorkspace as
|
|
114940
|
+
requireWorkspace as requireWorkspace5,
|
|
114900
114941
|
listOrganizationAdministrationMembers,
|
|
114901
114942
|
listOrganizationInvitations,
|
|
114902
114943
|
listSelfOrganizationInvitations,
|
|
114903
|
-
nestedPostgresSqlState as
|
|
114944
|
+
nestedPostgresSqlState as nestedPostgresSqlState17,
|
|
114904
114945
|
prepareOrganizationUserSetupDelivery,
|
|
114905
114946
|
revokeOrganizationInvitation,
|
|
114906
114947
|
settleOrganizationUserSetupDelivery,
|
|
@@ -114949,7 +114990,7 @@ async function requireOrganizationKeyWorkspaceDeletion(context, deps, organizati
|
|
|
114949
114990
|
message: "deleting an organization workspace requires an organization owner session or an organization API key with workspace:admin"
|
|
114950
114991
|
});
|
|
114951
114992
|
}
|
|
114952
|
-
const workspace = await
|
|
114993
|
+
const workspace = await requireWorkspace5(deps.db, workspaceId).catch(() => null);
|
|
114953
114994
|
if (!workspace || workspace.accountId !== organizationId2) {
|
|
114954
114995
|
throw new HTTPException112(404, { message: "workspace not found" });
|
|
114955
114996
|
}
|
|
@@ -115017,7 +115058,7 @@ function parseId(schema, value, label) {
|
|
|
115017
115058
|
return parsed.data;
|
|
115018
115059
|
}
|
|
115019
115060
|
function rethrowMembershipError(error, resourceLimitMessage) {
|
|
115020
|
-
const sqlState =
|
|
115061
|
+
const sqlState = nestedPostgresSqlState17(error);
|
|
115021
115062
|
if (sqlState === "54000" && resourceLimitMessage) {
|
|
115022
115063
|
throw new HTTPException112(409, {
|
|
115023
115064
|
message: resourceLimitMessage
|
|
@@ -115123,7 +115164,7 @@ function registerOrganizationMembershipRoutes(app, deps) {
|
|
|
115123
115164
|
})
|
|
115124
115165
|
);
|
|
115125
115166
|
} catch (error) {
|
|
115126
|
-
if (
|
|
115167
|
+
if (nestedPostgresSqlState17(error) === "42501") {
|
|
115127
115168
|
throw new HTTPException112(403, {
|
|
115128
115169
|
message: "organization membership is not active"
|
|
115129
115170
|
});
|
|
@@ -116266,7 +116307,7 @@ import {
|
|
|
116266
116307
|
completeSelfServiceOrganizationSetup,
|
|
116267
116308
|
completeOrganizationUserSetup,
|
|
116268
116309
|
getSelfServiceOrganizationOnboardingState,
|
|
116269
|
-
nestedPostgresSqlState as
|
|
116310
|
+
nestedPostgresSqlState as nestedPostgresSqlState18,
|
|
116270
116311
|
preflightOrganizationUserSetup,
|
|
116271
116312
|
previewOrganizationUserSetup,
|
|
116272
116313
|
recordOrganizationSignupUseCase
|
|
@@ -116324,14 +116365,14 @@ function registerManagedOnboardingRoutes(app, deps, options = {}) {
|
|
|
116324
116365
|
useCase: parsed.data.useCase
|
|
116325
116366
|
}).catch((error) => {
|
|
116326
116367
|
console.warn("[api] could not record the signup use case", {
|
|
116327
|
-
sqlState:
|
|
116368
|
+
sqlState: nestedPostgresSqlState18(error) ?? null
|
|
116328
116369
|
});
|
|
116329
116370
|
});
|
|
116330
116371
|
}
|
|
116331
116372
|
return context.json(completed);
|
|
116332
116373
|
} catch (error) {
|
|
116333
116374
|
recordOrganizationSetupOutcome(deps.observability, "failed");
|
|
116334
|
-
const sqlState =
|
|
116375
|
+
const sqlState = nestedPostgresSqlState18(error);
|
|
116335
116376
|
if (sqlState === "22023") {
|
|
116336
116377
|
throw new HTTPException115(422, {
|
|
116337
116378
|
message: "invalid organization setup request"
|
|
@@ -116411,7 +116452,7 @@ function registerManagedOnboardingRoutes(app, deps, options = {}) {
|
|
|
116411
116452
|
)
|
|
116412
116453
|
);
|
|
116413
116454
|
} catch (error) {
|
|
116414
|
-
const sqlState =
|
|
116455
|
+
const sqlState = nestedPostgresSqlState18(error);
|
|
116415
116456
|
if (sqlState === "22023") {
|
|
116416
116457
|
throw new HTTPException115(422, {
|
|
116417
116458
|
message: "invalid account setup request"
|
|
@@ -116532,7 +116573,7 @@ import {
|
|
|
116532
116573
|
SessionAuthorizationUnavailableError as SessionAuthorizationUnavailableError15,
|
|
116533
116574
|
SessionTenancyManagedHumanRequiredError as SessionTenancyManagedHumanRequiredError3
|
|
116534
116575
|
} from "@opengeni/core";
|
|
116535
|
-
import { nestedPostgresSqlState as
|
|
116576
|
+
import { nestedPostgresSqlState as nestedPostgresSqlState19, SessionTenancyNotActivatedError as SessionTenancyNotActivatedError3 } from "@opengeni/db";
|
|
116536
116577
|
import { HTTPException as HTTPException116 } from "hono/http-exception";
|
|
116537
116578
|
import { z as z62 } from "zod";
|
|
116538
116579
|
async function body2(context, schema) {
|
|
@@ -116547,10 +116588,10 @@ function lifecycleError(error) {
|
|
|
116547
116588
|
if (error instanceof SessionAuthorizationUnavailableError15) {
|
|
116548
116589
|
throw new HTTPException116(503, { message: "session authorization unavailable" });
|
|
116549
116590
|
}
|
|
116550
|
-
if (
|
|
116591
|
+
if (nestedPostgresSqlState19(error) === "42501") {
|
|
116551
116592
|
throw new HTTPException116(403, { message: "user-resource authority denied" });
|
|
116552
116593
|
}
|
|
116553
|
-
if (
|
|
116594
|
+
if (nestedPostgresSqlState19(error) === "22023") {
|
|
116554
116595
|
throw new HTTPException116(422, { message: "invalid user-resource request" });
|
|
116555
116596
|
}
|
|
116556
116597
|
throw error;
|
|
@@ -123141,6 +123182,10 @@ function createAppComposition(deps) {
|
|
|
123141
123182
|
"X-OpenGeni-Access-Key",
|
|
123142
123183
|
"X-OpenGeni-Api-Contract",
|
|
123143
123184
|
"X-OpenGeni-Actor-Epoch",
|
|
123185
|
+
// Resumable voice-input chunk integrity/timing (cross-origin embeds).
|
|
123186
|
+
"X-OpenGeni-Chunk-Duration-Milliseconds",
|
|
123187
|
+
"X-OpenGeni-Chunk-Sha256",
|
|
123188
|
+
"X-OpenGeni-Chunk-Start-Milliseconds",
|
|
123144
123189
|
"X-OpenGeni-Correlation-Id",
|
|
123145
123190
|
"X-OpenGeni-Session-Csrf",
|
|
123146
123191
|
// Session scope for a session proxy; the API itself ignores it.
|
|
@@ -124240,13 +124285,13 @@ function createAppComposition(deps) {
|
|
|
124240
124285
|
latencyMode: rawError.latencyMode,
|
|
124241
124286
|
allowedLatencyModes: [...rawError.allowedLatencyModes]
|
|
124242
124287
|
}
|
|
124243
|
-
}) : null) ?? requestBodyValidationHttpError(rawError) ?? invalidPathIdentifierHttpError(rawError, new URL(c.req.url).pathname) ?? databaseUnavailableHttpError(rawError, c.req.method) ?? rawError;
|
|
124288
|
+
}) : null) ?? requestBodyValidationHttpError(rawError) ?? invalidPathIdentifierHttpError(rawError, new URL(c.req.url).pathname) ?? databaseUnavailableHttpError(rawError, c.req.method) ?? databaseContentionHttpError(rawError, c.req.method) ?? rawError;
|
|
124244
124289
|
const compactionLock = codexCompactionV2ProviderLockedError(error);
|
|
124245
124290
|
const apiError = error instanceof ApiHttpError ? error : null;
|
|
124246
124291
|
const status = compactionLock ? 422 : httpStatusForError(error);
|
|
124247
124292
|
const code = compactionLock ? compactionLock.code : apiError?.code ?? errorCodeForStatus(status);
|
|
124248
124293
|
if (status >= 500) logHttpFailure(c, status, code, rawError);
|
|
124249
|
-
if (apiError?.details?.code === DATABASE_UNAVAILABLE_ERROR_DETAIL_CODE) {
|
|
124294
|
+
if (apiError?.details?.code === DATABASE_UNAVAILABLE_ERROR_DETAIL_CODE || apiError?.details?.code === DATABASE_CONTENTION_ERROR_DETAIL_CODE) {
|
|
124250
124295
|
c.header("retry-after", "1");
|
|
124251
124296
|
}
|
|
124252
124297
|
const envelope = ErrorEnvelope.parse({
|
|
@@ -124467,6 +124512,8 @@ function assertConfiguredCodemodeSessionProxyPath(session, path, method) {
|
|
|
124467
124512
|
}
|
|
124468
124513
|
}
|
|
124469
124514
|
function codemodeHttpError(error) {
|
|
124515
|
+
const contention = databaseContentionHttpError(error, "POST", { outcomeUnknown: false });
|
|
124516
|
+
if (contention) return contention;
|
|
124470
124517
|
if (error instanceof SiteSessionPathError) {
|
|
124471
124518
|
return new HTTPException118(404, { message: error.message, cause: error });
|
|
124472
124519
|
}
|
|
@@ -125706,4 +125753,4 @@ export {
|
|
|
125706
125753
|
withDefaultEnabledCapabilityMcpTools,
|
|
125707
125754
|
workflowIdForSession4 as workflowIdForSession
|
|
125708
125755
|
};
|
|
125709
|
-
//# sourceMappingURL=chunk-
|
|
125756
|
+
//# sourceMappingURL=chunk-F3LQ6VWR.js.map
|