@opengeni/db 0.27.9 → 0.27.11
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/{chunk-NX2JNJJP.js → chunk-JYQPJ6Y5.js} +52 -47
- package/dist/chunk-JYQPJ6Y5.js.map +1 -0
- package/dist/{chunk-2JFRTKTG.js → chunk-RPHPNVWW.js} +3 -1
- package/dist/chunk-RPHPNVWW.js.map +1 -0
- package/dist/index.d.ts +62 -30
- package/dist/index.js +303 -90
- package/dist/index.js.map +1 -1
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +2 -2
- package/dist/schema.d.ts +128 -96
- package/dist/schema.js +3 -1
- package/drizzle/0172_retire_model_visible_github_token.sql +86 -0
- package/drizzle/0173_codex_auth_boundaries.sql +107 -0
- package/drizzle/0174_session_wake_live_interruption.sql +80 -0
- package/package.json +4 -4
- package/src/index.ts +468 -166
- package/src/runtime-posture.ts +2 -0
- package/src/schema.ts +59 -47
- package/dist/chunk-2JFRTKTG.js.map +0 -1
- package/dist/chunk-NX2JNJJP.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
billingCustomers,
|
|
6
6
|
capabilityCatalogItems,
|
|
7
7
|
capabilityInstallations,
|
|
8
|
+
codexAppsSettings,
|
|
8
9
|
codexCapacityWaiters,
|
|
9
10
|
codexCredentialLeases,
|
|
10
11
|
codexResetRedemptionAttempts,
|
|
@@ -114,7 +115,7 @@ import {
|
|
|
114
115
|
workspaceVariableSetVariables,
|
|
115
116
|
workspaceVariableSets,
|
|
116
117
|
workspaces
|
|
117
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-JYQPJ6Y5.js";
|
|
118
119
|
import {
|
|
119
120
|
migrate,
|
|
120
121
|
runMigrations
|
|
@@ -134,7 +135,7 @@ import {
|
|
|
134
135
|
inspectRuntimeDatabasePosture,
|
|
135
136
|
provisionRoles,
|
|
136
137
|
runtimeDatabaseReadyCheck
|
|
137
|
-
} from "./chunk-
|
|
138
|
+
} from "./chunk-RPHPNVWW.js";
|
|
138
139
|
import "./chunk-PZ5AY32C.js";
|
|
139
140
|
|
|
140
141
|
// src/index.ts
|
|
@@ -20451,11 +20452,10 @@ async function upsertCodexSubscriptionCredential(db, input) {
|
|
|
20451
20452
|
// it when still null) so a re-connect never clobbers a rename.
|
|
20452
20453
|
accountEmail: input.accountEmail ?? null,
|
|
20453
20454
|
label: sql15`coalesce(${codexSubscriptionCredentials.label}, ${input.label ?? null})`,
|
|
20454
|
-
//
|
|
20455
|
-
//
|
|
20456
|
-
//
|
|
20457
|
-
|
|
20458
|
-
connectedBySubjectId: input.connectedBySubjectId ?? null,
|
|
20455
|
+
// Reconnect refreshes credential material, never ownership. A row
|
|
20456
|
+
// without an owner may be claimed by its first direct managed human;
|
|
20457
|
+
// after that, disconnect is the explicit ownership-reset boundary.
|
|
20458
|
+
connectedBySubjectId: sql15`coalesce(${codexSubscriptionCredentials.connectedBySubjectId}, ${input.connectedBySubjectId ?? null})`,
|
|
20459
20459
|
status: "active",
|
|
20460
20460
|
lastError: null,
|
|
20461
20461
|
version: sql15`${codexSubscriptionCredentials.version} + 1`,
|
|
@@ -20474,6 +20474,198 @@ async function upsertCodexSubscriptionCredential(db, input) {
|
|
|
20474
20474
|
}
|
|
20475
20475
|
);
|
|
20476
20476
|
}
|
|
20477
|
+
async function getCodexAppsSettings(db, workspaceId) {
|
|
20478
|
+
return await withWorkspaceRls(db, workspaceId, async (scopedDb) => {
|
|
20479
|
+
const [row] = await scopedDb.select({
|
|
20480
|
+
credentialId: codexAppsSettings.credentialId,
|
|
20481
|
+
version: codexAppsSettings.version,
|
|
20482
|
+
designatedAt: codexAppsSettings.designatedAt
|
|
20483
|
+
}).from(codexAppsSettings).where(eq18(codexAppsSettings.workspaceId, workspaceId)).limit(1);
|
|
20484
|
+
return row ?? { credentialId: null, version: 0, designatedAt: null };
|
|
20485
|
+
});
|
|
20486
|
+
}
|
|
20487
|
+
function canManageCodexApps(permissions) {
|
|
20488
|
+
return Array.isArray(permissions) && (permissions.includes("connections:write") || permissions.includes("workspace:admin"));
|
|
20489
|
+
}
|
|
20490
|
+
var CodexAppsAuthorizationRevokedError = class extends Error {
|
|
20491
|
+
constructor() {
|
|
20492
|
+
super("Codex Apps authorization is no longer active");
|
|
20493
|
+
this.name = "CodexAppsAuthorizationRevokedError";
|
|
20494
|
+
}
|
|
20495
|
+
};
|
|
20496
|
+
async function getCodexAppsCredentialAuthorizationForRun(db, workspaceId) {
|
|
20497
|
+
return await withWorkspaceRls(db, workspaceId, async (scopedDb) => {
|
|
20498
|
+
const [row] = await scopedDb.select({
|
|
20499
|
+
credentialId: codexAppsSettings.credentialId,
|
|
20500
|
+
ownerSubjectId: codexSubscriptionCredentials.connectedBySubjectId
|
|
20501
|
+
}).from(codexAppsSettings).innerJoin(
|
|
20502
|
+
codexSubscriptionCredentials,
|
|
20503
|
+
and17(
|
|
20504
|
+
eq18(codexSubscriptionCredentials.id, codexAppsSettings.credentialId),
|
|
20505
|
+
eq18(codexSubscriptionCredentials.accountId, codexAppsSettings.accountId),
|
|
20506
|
+
eq18(codexSubscriptionCredentials.workspaceId, workspaceId),
|
|
20507
|
+
eq18(codexSubscriptionCredentials.status, "active")
|
|
20508
|
+
)
|
|
20509
|
+
).where(eq18(codexAppsSettings.workspaceId, workspaceId)).limit(1);
|
|
20510
|
+
return row?.credentialId && row.ownerSubjectId ? { credentialId: row.credentialId, ownerSubjectId: row.ownerSubjectId } : null;
|
|
20511
|
+
});
|
|
20512
|
+
}
|
|
20513
|
+
async function withCodexAppsRequestAuthorization(db, input, use) {
|
|
20514
|
+
return await withWorkspaceRls(db, input.workspaceId, async (scopedDb) => {
|
|
20515
|
+
await scopedDb.execute(
|
|
20516
|
+
sql15`select pg_advisory_xact_lock(hashtextextended(${`codex-apps-settings:${input.workspaceId}`}, 0))`
|
|
20517
|
+
);
|
|
20518
|
+
const [designation] = await scopedDb.select({ credentialId: codexAppsSettings.credentialId }).from(codexAppsSettings).where(eq18(codexAppsSettings.workspaceId, input.workspaceId)).for("share").limit(1);
|
|
20519
|
+
if (designation?.credentialId !== input.credentialId) {
|
|
20520
|
+
throw new CodexAppsAuthorizationRevokedError();
|
|
20521
|
+
}
|
|
20522
|
+
const [credential] = await scopedDb.select({
|
|
20523
|
+
ownerSubjectId: codexSubscriptionCredentials.connectedBySubjectId,
|
|
20524
|
+
status: codexSubscriptionCredentials.status
|
|
20525
|
+
}).from(codexSubscriptionCredentials).where(
|
|
20526
|
+
and17(
|
|
20527
|
+
eq18(codexSubscriptionCredentials.workspaceId, input.workspaceId),
|
|
20528
|
+
eq18(codexSubscriptionCredentials.id, input.credentialId)
|
|
20529
|
+
)
|
|
20530
|
+
).for("share").limit(1);
|
|
20531
|
+
if (!credential?.ownerSubjectId || credential.status !== "active") {
|
|
20532
|
+
throw new CodexAppsAuthorizationRevokedError();
|
|
20533
|
+
}
|
|
20534
|
+
const [membership] = await scopedDb.select({ permissions: workspaceMemberships.permissions }).from(workspaceMemberships).where(
|
|
20535
|
+
and17(
|
|
20536
|
+
eq18(workspaceMemberships.workspaceId, input.workspaceId),
|
|
20537
|
+
eq18(workspaceMemberships.subjectId, credential.ownerSubjectId)
|
|
20538
|
+
)
|
|
20539
|
+
).for("share").limit(1);
|
|
20540
|
+
if (!canManageCodexApps(membership?.permissions)) {
|
|
20541
|
+
throw new CodexAppsAuthorizationRevokedError();
|
|
20542
|
+
}
|
|
20543
|
+
return await use();
|
|
20544
|
+
});
|
|
20545
|
+
}
|
|
20546
|
+
async function designateCodexAppsCredential(db, input) {
|
|
20547
|
+
return await withRlsContext(
|
|
20548
|
+
db,
|
|
20549
|
+
{ accountId: input.accountId, workspaceId: input.workspaceId },
|
|
20550
|
+
async (scopedDb) => {
|
|
20551
|
+
await scopedDb.execute(
|
|
20552
|
+
sql15`select pg_advisory_xact_lock(hashtextextended(${`codex-apps-settings:${input.workspaceId}`}, 0))`
|
|
20553
|
+
);
|
|
20554
|
+
const [currentRow] = await scopedDb.select().from(codexAppsSettings).where(eq18(codexAppsSettings.workspaceId, input.workspaceId)).for("update").limit(1);
|
|
20555
|
+
const current = currentRow ? {
|
|
20556
|
+
credentialId: currentRow.credentialId,
|
|
20557
|
+
version: currentRow.version,
|
|
20558
|
+
designatedAt: currentRow.designatedAt
|
|
20559
|
+
} : { credentialId: null, version: 0, designatedAt: null };
|
|
20560
|
+
if (current.version !== input.expectedVersion) return { kind: "conflict", ...current };
|
|
20561
|
+
if (current.credentialId !== null) return { kind: "already_designated", ...current };
|
|
20562
|
+
const [credential] = await scopedDb.select({
|
|
20563
|
+
connectedBySubjectId: codexSubscriptionCredentials.connectedBySubjectId,
|
|
20564
|
+
status: codexSubscriptionCredentials.status
|
|
20565
|
+
}).from(codexSubscriptionCredentials).where(
|
|
20566
|
+
and17(
|
|
20567
|
+
eq18(codexSubscriptionCredentials.accountId, input.accountId),
|
|
20568
|
+
eq18(codexSubscriptionCredentials.workspaceId, input.workspaceId),
|
|
20569
|
+
eq18(codexSubscriptionCredentials.id, input.credentialId)
|
|
20570
|
+
)
|
|
20571
|
+
).for("update").limit(1);
|
|
20572
|
+
if (!credential) return { kind: "not_found" };
|
|
20573
|
+
if (credential.connectedBySubjectId !== input.subjectId) return { kind: "not_owner" };
|
|
20574
|
+
if (credential.status !== "active") return { kind: "unavailable" };
|
|
20575
|
+
const [membership] = await scopedDb.select({ permissions: workspaceMemberships.permissions }).from(workspaceMemberships).where(
|
|
20576
|
+
and17(
|
|
20577
|
+
eq18(workspaceMemberships.accountId, input.accountId),
|
|
20578
|
+
eq18(workspaceMemberships.workspaceId, input.workspaceId),
|
|
20579
|
+
eq18(workspaceMemberships.subjectId, input.subjectId)
|
|
20580
|
+
)
|
|
20581
|
+
).for("update").limit(1);
|
|
20582
|
+
if (!canManageCodexApps(membership?.permissions)) return { kind: "forbidden" };
|
|
20583
|
+
const now = /* @__PURE__ */ new Date();
|
|
20584
|
+
const version = current.version + 1;
|
|
20585
|
+
const [updated] = await scopedDb.insert(codexAppsSettings).values({
|
|
20586
|
+
accountId: input.accountId,
|
|
20587
|
+
workspaceId: input.workspaceId,
|
|
20588
|
+
credentialId: input.credentialId,
|
|
20589
|
+
version,
|
|
20590
|
+
designatedAt: now,
|
|
20591
|
+
updatedAt: now
|
|
20592
|
+
}).onConflictDoUpdate({
|
|
20593
|
+
target: codexAppsSettings.workspaceId,
|
|
20594
|
+
set: {
|
|
20595
|
+
credentialId: input.credentialId,
|
|
20596
|
+
version,
|
|
20597
|
+
designatedAt: now,
|
|
20598
|
+
updatedAt: now
|
|
20599
|
+
}
|
|
20600
|
+
}).returning({
|
|
20601
|
+
credentialId: codexAppsSettings.credentialId,
|
|
20602
|
+
version: codexAppsSettings.version,
|
|
20603
|
+
designatedAt: codexAppsSettings.designatedAt
|
|
20604
|
+
});
|
|
20605
|
+
if (!updated?.credentialId || !updated.designatedAt) {
|
|
20606
|
+
throw new Error("Codex Apps designation was not persisted");
|
|
20607
|
+
}
|
|
20608
|
+
await scopedDb.insert(auditEvents).values({
|
|
20609
|
+
accountId: input.accountId,
|
|
20610
|
+
workspaceId: input.workspaceId,
|
|
20611
|
+
subjectId: input.subjectId,
|
|
20612
|
+
action: "codex_apps.designated",
|
|
20613
|
+
targetType: "codex_subscription_credential",
|
|
20614
|
+
targetId: input.credentialId,
|
|
20615
|
+
metadata: { version }
|
|
20616
|
+
});
|
|
20617
|
+
return { kind: "updated", ...updated };
|
|
20618
|
+
}
|
|
20619
|
+
);
|
|
20620
|
+
}
|
|
20621
|
+
async function clearCodexAppsCredential(db, input) {
|
|
20622
|
+
return await withRlsContext(
|
|
20623
|
+
db,
|
|
20624
|
+
{ accountId: input.accountId, workspaceId: input.workspaceId },
|
|
20625
|
+
async (scopedDb) => {
|
|
20626
|
+
await scopedDb.execute(
|
|
20627
|
+
sql15`select pg_advisory_xact_lock(hashtextextended(${`codex-apps-settings:${input.workspaceId}`}, 0))`
|
|
20628
|
+
);
|
|
20629
|
+
const [row] = await scopedDb.select().from(codexAppsSettings).where(eq18(codexAppsSettings.workspaceId, input.workspaceId)).for("update").limit(1);
|
|
20630
|
+
const current = row ? { credentialId: row.credentialId, version: row.version, designatedAt: row.designatedAt } : { credentialId: null, version: 0, designatedAt: null };
|
|
20631
|
+
const [membership] = await scopedDb.select({ permissions: workspaceMemberships.permissions }).from(workspaceMemberships).where(
|
|
20632
|
+
and17(
|
|
20633
|
+
eq18(workspaceMemberships.accountId, input.accountId),
|
|
20634
|
+
eq18(workspaceMemberships.workspaceId, input.workspaceId),
|
|
20635
|
+
eq18(workspaceMemberships.subjectId, input.subjectId)
|
|
20636
|
+
)
|
|
20637
|
+
).for("update").limit(1);
|
|
20638
|
+
if (!canManageCodexApps(membership?.permissions)) {
|
|
20639
|
+
return { kind: "forbidden", ...current };
|
|
20640
|
+
}
|
|
20641
|
+
if (current.version !== input.expectedVersion) return { kind: "conflict", ...current };
|
|
20642
|
+
if (current.credentialId === null) return { kind: "unchanged", ...current };
|
|
20643
|
+
const now = /* @__PURE__ */ new Date();
|
|
20644
|
+
const version = current.version + 1;
|
|
20645
|
+
const [updated] = await scopedDb.update(codexAppsSettings).set({
|
|
20646
|
+
credentialId: null,
|
|
20647
|
+
version,
|
|
20648
|
+
designatedAt: null,
|
|
20649
|
+
updatedAt: now
|
|
20650
|
+
}).where(eq18(codexAppsSettings.workspaceId, input.workspaceId)).returning({
|
|
20651
|
+
credentialId: codexAppsSettings.credentialId,
|
|
20652
|
+
version: codexAppsSettings.version,
|
|
20653
|
+
designatedAt: codexAppsSettings.designatedAt
|
|
20654
|
+
});
|
|
20655
|
+
if (!updated) throw new Error("Codex Apps designation clear was not persisted");
|
|
20656
|
+
await scopedDb.insert(auditEvents).values({
|
|
20657
|
+
accountId: input.accountId,
|
|
20658
|
+
workspaceId: input.workspaceId,
|
|
20659
|
+
subjectId: input.subjectId,
|
|
20660
|
+
action: "codex_apps.cleared",
|
|
20661
|
+
targetType: "codex_subscription_credential",
|
|
20662
|
+
targetId: current.credentialId,
|
|
20663
|
+
metadata: { version }
|
|
20664
|
+
});
|
|
20665
|
+
return { kind: "updated", ...updated };
|
|
20666
|
+
}
|
|
20667
|
+
);
|
|
20668
|
+
}
|
|
20477
20669
|
async function loadCodexCredentialForRun(db, settings, workspaceId, credentialId) {
|
|
20478
20670
|
const key = environmentsEncryptionKeyBytes(settings);
|
|
20479
20671
|
if (!key) {
|
|
@@ -20708,8 +20900,6 @@ function mapCodexLeaseCandidate(row, activeCredentialId) {
|
|
|
20708
20900
|
secondaryResetAt: codexMetadataDate(row.secondary_reset_at),
|
|
20709
20901
|
usageCheckedAt: codexMetadataDate(row.usage_checked_at),
|
|
20710
20902
|
exhaustedUntil: codexMetadataDate(row.exhausted_until),
|
|
20711
|
-
connectorNamespaces: row.connector_namespaces,
|
|
20712
|
-
connectorsCheckedAt: codexMetadataDate(row.connectors_checked_at),
|
|
20713
20903
|
selectionCount: Number(row.selection_count),
|
|
20714
20904
|
lastSelectedAt: codexMetadataDate(row.last_selected_at),
|
|
20715
20905
|
activeLeaseCount: Number(row.active_lease_count)
|
|
@@ -20750,8 +20940,6 @@ async function listCodexLeaseCandidatesInTransaction(tx, input) {
|
|
|
20750
20940
|
c.secondary_reset_at,
|
|
20751
20941
|
c.usage_checked_at,
|
|
20752
20942
|
c.exhausted_until,
|
|
20753
|
-
c.connector_namespaces,
|
|
20754
|
-
c.connectors_checked_at,
|
|
20755
20943
|
c.selection_count,
|
|
20756
20944
|
c.last_selected_at,
|
|
20757
20945
|
count(l.id) filter (
|
|
@@ -20809,18 +20997,6 @@ async function acquireCodexCredentialLease(db, input, select) {
|
|
|
20809
20997
|
throw new Error(`Session turn not found for Codex lease: ${input.turnId}`);
|
|
20810
20998
|
}
|
|
20811
20999
|
const policyScope = input.resolvePolicyScope?.(turns[0].metadata ?? {}) ?? null;
|
|
20812
|
-
const continuationRows = input.continuationCredentialId ? await tx.execute(
|
|
20813
|
-
sql15`
|
|
20814
|
-
select frozen_codex_credential_id
|
|
20815
|
-
from agent_run_states
|
|
20816
|
-
where account_id = ${input.accountId}
|
|
20817
|
-
and workspace_id = ${input.workspaceId}
|
|
20818
|
-
and turn_id = ${input.turnId}
|
|
20819
|
-
order by state_version desc
|
|
20820
|
-
limit 1
|
|
20821
|
-
`
|
|
20822
|
-
) : [];
|
|
20823
|
-
const validatedContinuationCredentialId = continuationRows[0]?.frozen_codex_credential_id === input.continuationCredentialId ? input.continuationCredentialId : null;
|
|
20824
21000
|
const activeCredentialId = settingsRow.active_credential_id;
|
|
20825
21001
|
const rotationEnabled = settingsRow.rotation_enabled;
|
|
20826
21002
|
const leaseRotationEnabled = settingsRow.rotation_enabled && settingsRow.lease_rotation_enabled;
|
|
@@ -20847,7 +21023,7 @@ async function acquireCodexCredentialLease(db, input, select) {
|
|
|
20847
21023
|
activeCredentialId,
|
|
20848
21024
|
excludeTurnId: input.turnId
|
|
20849
21025
|
});
|
|
20850
|
-
const sameTurnCredentialId = existingCredentialId
|
|
21026
|
+
const sameTurnCredentialId = existingCredentialId;
|
|
20851
21027
|
const selectionContext = (accounts2, unavailableDiagnostics2) => ({
|
|
20852
21028
|
accounts: accounts2,
|
|
20853
21029
|
activeCredentialId,
|
|
@@ -20903,7 +21079,7 @@ async function acquireCodexCredentialLease(db, input, select) {
|
|
|
20903
21079
|
if (!selectedAccount) {
|
|
20904
21080
|
throw new Error("Codex lease selector returned a credential outside the workspace pool");
|
|
20905
21081
|
}
|
|
20906
|
-
if (!selectedAccount.allocatorEnabled && selectedAccount.id !== existingCredentialId
|
|
21082
|
+
if (!selectedAccount.allocatorEnabled && selectedAccount.id !== existingCredentialId) {
|
|
20907
21083
|
throw new Error("Codex lease selector returned a credential disabled for new allocations");
|
|
20908
21084
|
}
|
|
20909
21085
|
const advanceActivePointer = input.advanceActivePointer && selected.advanceActivePointer !== false;
|
|
@@ -21816,10 +21992,7 @@ async function listCodexAccountStatuses(db, workspaceId) {
|
|
|
21816
21992
|
secondaryUsedPercent: codexSubscriptionCredentials.secondaryUsedPercent,
|
|
21817
21993
|
secondaryResetAt: codexSubscriptionCredentials.secondaryResetAt,
|
|
21818
21994
|
usageCheckedAt: codexSubscriptionCredentials.usageCheckedAt,
|
|
21819
|
-
exhaustedUntil: codexSubscriptionCredentials.exhaustedUntil
|
|
21820
|
-
// P4 connector-set cache — metadata-only, rides along on this read.
|
|
21821
|
-
connectorNamespaces: codexSubscriptionCredentials.connectorNamespaces,
|
|
21822
|
-
connectorsCheckedAt: codexSubscriptionCredentials.connectorsCheckedAt
|
|
21995
|
+
exhaustedUntil: codexSubscriptionCredentials.exhaustedUntil
|
|
21823
21996
|
}).from(codexSubscriptionCredentials).where(eq18(codexSubscriptionCredentials.workspaceId, workspaceId)).orderBy(
|
|
21824
21997
|
asc8(codexSubscriptionCredentials.createdAt),
|
|
21825
21998
|
asc8(codexSubscriptionCredentials.id)
|
|
@@ -21834,7 +22007,6 @@ async function listCodexAccountStatuses(db, workspaceId) {
|
|
|
21834
22007
|
secondaryResetAt: codexMetadataDate(row.secondaryResetAt),
|
|
21835
22008
|
usageCheckedAt: codexMetadataDate(row.usageCheckedAt),
|
|
21836
22009
|
exhaustedUntil: codexMetadataDate(row.exhaustedUntil),
|
|
21837
|
-
connectorsCheckedAt: codexMetadataDate(row.connectorsCheckedAt),
|
|
21838
22010
|
isActive: row.id === activeId
|
|
21839
22011
|
}));
|
|
21840
22012
|
});
|
|
@@ -22552,23 +22724,6 @@ async function countConsecutiveReactiveRotations(db, workspaceId, sessionId) {
|
|
|
22552
22724
|
return Number(rotated);
|
|
22553
22725
|
});
|
|
22554
22726
|
}
|
|
22555
|
-
async function recordCodexAccountConnectors(db, workspaceId, credentialId, namespaces) {
|
|
22556
|
-
return await withWorkspaceRls(db, workspaceId, async (scopedDb) => {
|
|
22557
|
-
const updated = await scopedDb.update(codexSubscriptionCredentials).set({
|
|
22558
|
-
connectorNamespaces: namespaces,
|
|
22559
|
-
connectorsCheckedAt: /* @__PURE__ */ new Date()
|
|
22560
|
-
// NB: no `version` bump and no `updatedAt` touch — connector set is non-credential
|
|
22561
|
-
// metadata and must NOT race the (id, version) refresh CAS (same discipline as
|
|
22562
|
-
// recordCodexAccountUsage / setCodexCredentialExhausted).
|
|
22563
|
-
}).where(
|
|
22564
|
-
and17(
|
|
22565
|
-
eq18(codexSubscriptionCredentials.id, credentialId),
|
|
22566
|
-
eq18(codexSubscriptionCredentials.workspaceId, workspaceId)
|
|
22567
|
-
)
|
|
22568
|
-
).returning({ id: codexSubscriptionCredentials.id });
|
|
22569
|
-
return updated.length > 0;
|
|
22570
|
-
});
|
|
22571
|
-
}
|
|
22572
22727
|
var CODEX_ROTATION_STRATEGIES = [
|
|
22573
22728
|
"most_remaining",
|
|
22574
22729
|
"round_robin",
|
|
@@ -22667,14 +22822,21 @@ async function recordSessionActiveCodexCredential(db, workspaceId, sessionId, cr
|
|
|
22667
22822
|
await scopedDb.update(sessions).set({ codexLastCredentialId: credentialId, updatedAt: /* @__PURE__ */ new Date() }).where(and17(eq18(sessions.workspaceId, workspaceId), eq18(sessions.id, sessionId)));
|
|
22668
22823
|
});
|
|
22669
22824
|
}
|
|
22670
|
-
async function disconnectCodexAccount(db, workspaceId, credentialId) {
|
|
22825
|
+
async function disconnectCodexAccount(db, workspaceId, credentialId, actorSubjectId = null) {
|
|
22671
22826
|
return await withWorkspaceRls(db, workspaceId, async (scopedDb) => {
|
|
22672
22827
|
await scopedDb.execute(sql15`
|
|
22673
22828
|
select id from codex_rotation_settings
|
|
22674
22829
|
where workspace_id = ${workspaceId}
|
|
22675
22830
|
for update
|
|
22676
22831
|
`);
|
|
22677
|
-
|
|
22832
|
+
await scopedDb.execute(
|
|
22833
|
+
sql15`select pg_advisory_xact_lock(hashtextextended(${`codex-apps-settings:${workspaceId}`}, 0))`
|
|
22834
|
+
);
|
|
22835
|
+
const [appsSettings] = await scopedDb.select().from(codexAppsSettings).where(eq18(codexAppsSettings.workspaceId, workspaceId)).for("update").limit(1);
|
|
22836
|
+
const [credential] = await scopedDb.select({
|
|
22837
|
+
id: codexSubscriptionCredentials.id,
|
|
22838
|
+
accountId: codexSubscriptionCredentials.accountId
|
|
22839
|
+
}).from(codexSubscriptionCredentials).where(
|
|
22678
22840
|
and17(
|
|
22679
22841
|
eq18(codexSubscriptionCredentials.id, credentialId),
|
|
22680
22842
|
eq18(codexSubscriptionCredentials.workspaceId, workspaceId)
|
|
@@ -22704,6 +22866,24 @@ async function disconnectCodexAccount(db, workspaceId, credentialId) {
|
|
|
22704
22866
|
blockedByUnresolvedRedemption: true
|
|
22705
22867
|
};
|
|
22706
22868
|
}
|
|
22869
|
+
if (appsSettings?.credentialId === credentialId) {
|
|
22870
|
+
const version = appsSettings.version + 1;
|
|
22871
|
+
await scopedDb.update(codexAppsSettings).set({
|
|
22872
|
+
credentialId: null,
|
|
22873
|
+
version,
|
|
22874
|
+
designatedAt: null,
|
|
22875
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
22876
|
+
}).where(eq18(codexAppsSettings.id, appsSettings.id));
|
|
22877
|
+
await scopedDb.insert(auditEvents).values({
|
|
22878
|
+
accountId: credential.accountId,
|
|
22879
|
+
workspaceId,
|
|
22880
|
+
subjectId: actorSubjectId,
|
|
22881
|
+
action: "codex_apps.cleared_on_disconnect",
|
|
22882
|
+
targetType: "codex_subscription_credential",
|
|
22883
|
+
targetId: credentialId,
|
|
22884
|
+
metadata: { version }
|
|
22885
|
+
});
|
|
22886
|
+
}
|
|
22707
22887
|
const removedRows = await scopedDb.delete(codexSubscriptionCredentials).where(
|
|
22708
22888
|
and17(
|
|
22709
22889
|
eq18(codexSubscriptionCredentials.id, credentialId),
|
|
@@ -22735,9 +22915,16 @@ async function disconnectCodexAccount(db, workspaceId, credentialId) {
|
|
|
22735
22915
|
};
|
|
22736
22916
|
});
|
|
22737
22917
|
}
|
|
22738
|
-
async function disconnectAllCodexAccounts(db, workspaceId) {
|
|
22918
|
+
async function disconnectAllCodexAccounts(db, workspaceId, actorSubjectId = null) {
|
|
22739
22919
|
return await withWorkspaceRls(db, workspaceId, async (scopedDb) => {
|
|
22740
|
-
|
|
22920
|
+
await scopedDb.execute(
|
|
22921
|
+
sql15`select pg_advisory_xact_lock(hashtextextended(${`codex-apps-settings:${workspaceId}`}, 0))`
|
|
22922
|
+
);
|
|
22923
|
+
const [appsSettings] = await scopedDb.select().from(codexAppsSettings).where(eq18(codexAppsSettings.workspaceId, workspaceId)).for("update").limit(1);
|
|
22924
|
+
const credentials = await scopedDb.select({
|
|
22925
|
+
id: codexSubscriptionCredentials.id,
|
|
22926
|
+
accountId: codexSubscriptionCredentials.accountId
|
|
22927
|
+
}).from(codexSubscriptionCredentials).where(eq18(codexSubscriptionCredentials.workspaceId, workspaceId)).orderBy(asc8(codexSubscriptionCredentials.id)).for("update");
|
|
22741
22928
|
if (credentials.length === 0) return { removed: 0, blockedCredentialIds: [] };
|
|
22742
22929
|
const blocked = await scopedDb.selectDistinct({
|
|
22743
22930
|
credentialId: codexResetRedemptionAttempts.credentialId
|
|
@@ -22753,6 +22940,24 @@ async function disconnectAllCodexAccounts(db, workspaceId) {
|
|
|
22753
22940
|
blockedCredentialIds: blocked.map((row) => row.credentialId).sort()
|
|
22754
22941
|
};
|
|
22755
22942
|
}
|
|
22943
|
+
if (appsSettings?.credentialId) {
|
|
22944
|
+
const version = appsSettings.version + 1;
|
|
22945
|
+
await scopedDb.update(codexAppsSettings).set({
|
|
22946
|
+
credentialId: null,
|
|
22947
|
+
version,
|
|
22948
|
+
designatedAt: null,
|
|
22949
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
22950
|
+
}).where(eq18(codexAppsSettings.id, appsSettings.id));
|
|
22951
|
+
await scopedDb.insert(auditEvents).values({
|
|
22952
|
+
accountId: credentials[0].accountId,
|
|
22953
|
+
workspaceId,
|
|
22954
|
+
subjectId: actorSubjectId,
|
|
22955
|
+
action: "codex_apps.cleared_on_disconnect",
|
|
22956
|
+
targetType: "codex_subscription_credential",
|
|
22957
|
+
targetId: appsSettings.credentialId,
|
|
22958
|
+
metadata: { version }
|
|
22959
|
+
});
|
|
22960
|
+
}
|
|
22756
22961
|
const rows = await scopedDb.delete(codexSubscriptionCredentials).where(eq18(codexSubscriptionCredentials.workspaceId, workspaceId)).returning({ id: codexSubscriptionCredentials.id });
|
|
22757
22962
|
return { removed: rows.length, blockedCredentialIds: [] };
|
|
22758
22963
|
});
|
|
@@ -23707,6 +23912,13 @@ async function lockSessionCreateIdempotencyKey(tx, workspaceId, createIdempotenc
|
|
|
23707
23912
|
sql15`select pg_advisory_xact_lock(hashtext(${`session-create:${workspaceId}:${createIdempotencyKey}`}))`
|
|
23708
23913
|
);
|
|
23709
23914
|
}
|
|
23915
|
+
async function lockAgentSessionCreate(tx, input) {
|
|
23916
|
+
const actorSessionId = input.createdByActor?.sessionId;
|
|
23917
|
+
if (!actorSessionId) return;
|
|
23918
|
+
await tx.execute(
|
|
23919
|
+
sql15`select pg_advisory_xact_lock(hashtextextended(${`agent-session-create:${input.workspaceId}:${actorSessionId}`}, 0))`
|
|
23920
|
+
);
|
|
23921
|
+
}
|
|
23710
23922
|
async function existingSpawnDenialForKey(tx, workspaceId, createIdempotencyKey) {
|
|
23711
23923
|
const [existing] = await tx.select().from(sessionSpawnDenials).where(
|
|
23712
23924
|
and17(
|
|
@@ -23780,6 +23992,7 @@ async function createSessionInTransaction(tx, input, id) {
|
|
|
23780
23992
|
};
|
|
23781
23993
|
}
|
|
23782
23994
|
}
|
|
23995
|
+
await lockAgentSessionCreate(tx, input);
|
|
23783
23996
|
const decision = await resolveSessionDepthDecision(tx, input, id, workspace, deploymentPolicy);
|
|
23784
23997
|
if (decision.denied) {
|
|
23785
23998
|
return {
|
|
@@ -25754,7 +25967,6 @@ async function getLatestRunState(db, workspaceId, sessionId) {
|
|
|
25754
25967
|
turnId: row.turnId ?? null,
|
|
25755
25968
|
serializedRunState: row.serializedRunState,
|
|
25756
25969
|
pendingApprovals: row.pendingApprovals,
|
|
25757
|
-
frozenCodexCredentialId: row.frozenCodexCredentialId ?? null,
|
|
25758
25970
|
providerArtifactInvalidatedAt: row.providerArtifactInvalidatedAt ?? null
|
|
25759
25971
|
} : null;
|
|
25760
25972
|
});
|
|
@@ -26255,7 +26467,6 @@ async function appendSessionHistoryItems(db, input) {
|
|
|
26255
26467
|
workspaceId: input.workspaceId,
|
|
26256
26468
|
sessionId: input.sessionId,
|
|
26257
26469
|
turnId: input.turnId,
|
|
26258
|
-
producerCodexCredentialId: input.producerCodexCredentialId ?? null,
|
|
26259
26470
|
position: entry.position,
|
|
26260
26471
|
// This is the canonical model-memory boundary. The pending-call
|
|
26261
26472
|
// ledger and audit event may retain their separate raw/preview
|
|
@@ -26497,9 +26708,9 @@ async function getSessionHistoryItems(db, workspaceId, sessionId) {
|
|
|
26497
26708
|
async function getActiveSessionHistoryItems(db, workspaceId, sessionId) {
|
|
26498
26709
|
return await withWorkspaceRls(db, workspaceId, async (scopedDb) => {
|
|
26499
26710
|
const rows = await scopedDb.select({
|
|
26711
|
+
id: sessionHistoryItems.id,
|
|
26500
26712
|
position: sessionHistoryItems.position,
|
|
26501
26713
|
item: sessionHistoryItems.item,
|
|
26502
|
-
producerCodexCredentialId: sessionHistoryItems.producerCodexCredentialId,
|
|
26503
26714
|
providerArtifactInvalidatedAt: sessionHistoryItems.providerArtifactInvalidatedAt
|
|
26504
26715
|
}).from(sessionHistoryItems).where(
|
|
26505
26716
|
and17(
|
|
@@ -26633,8 +26844,7 @@ async function applyContextCompaction(db, input) {
|
|
|
26633
26844
|
turnId: null,
|
|
26634
26845
|
position: supersededFrom + index,
|
|
26635
26846
|
item: sanitizeModelPayload(item),
|
|
26636
|
-
active: true
|
|
26637
|
-
...input.producerCodexCredentialId ? { producerCodexCredentialId: input.producerCodexCredentialId } : {}
|
|
26847
|
+
active: true
|
|
26638
26848
|
}))
|
|
26639
26849
|
);
|
|
26640
26850
|
}
|
|
@@ -26646,8 +26856,7 @@ async function applyContextCompaction(db, input) {
|
|
|
26646
26856
|
turnId: input.turnId,
|
|
26647
26857
|
position: summaryPosition,
|
|
26648
26858
|
item: sanitizeModelPayload(input.summaryItem),
|
|
26649
|
-
active: true
|
|
26650
|
-
...input.producerCodexCredentialId ? { producerCodexCredentialId: input.producerCodexCredentialId } : {}
|
|
26859
|
+
active: true
|
|
26651
26860
|
});
|
|
26652
26861
|
const insertedEvents = input.eventPayload ? await tx.insert(sessionEvents).values({
|
|
26653
26862
|
accountId: input.accountId,
|
|
@@ -33784,8 +33993,7 @@ async function saveRunState(db, input) {
|
|
|
33784
33993
|
turnId: input.turnId,
|
|
33785
33994
|
stateVersion: Number(maxVersion) + 1,
|
|
33786
33995
|
serializedRunState: input.serializedRunState,
|
|
33787
|
-
pendingApprovals: input.pendingApprovals
|
|
33788
|
-
frozenCodexCredentialId: input.frozenCodexCredentialId ?? null
|
|
33996
|
+
pendingApprovals: input.pendingApprovals
|
|
33789
33997
|
});
|
|
33790
33998
|
return true;
|
|
33791
33999
|
});
|
|
@@ -35621,8 +35829,7 @@ async function claimSessionWorkForAttempt(db, workspaceId, input) {
|
|
|
35621
35829
|
sessionId,
|
|
35622
35830
|
turnId,
|
|
35623
35831
|
position: Number(position),
|
|
35624
|
-
item: sanitizeModelPayload(delivered2.historyItem)
|
|
35625
|
-
producerCodexCredentialId: null
|
|
35832
|
+
item: sanitizeModelPayload(delivered2.historyItem)
|
|
35626
35833
|
});
|
|
35627
35834
|
};
|
|
35628
35835
|
const workspaceControl = await lockWorkspaceInferenceControl(
|
|
@@ -36408,8 +36615,7 @@ async function claimSessionWorkForAttempt(db, workspaceId, input) {
|
|
|
36408
36615
|
item: durableUserHistoryItem(
|
|
36409
36616
|
row.prompt,
|
|
36410
36617
|
Array.isArray(row.resources) ? row.resources : []
|
|
36411
|
-
)
|
|
36412
|
-
producerCodexCredentialId: null
|
|
36618
|
+
)
|
|
36413
36619
|
});
|
|
36414
36620
|
const providerDelegatedTurn = isSessionRealtimeDelegationTurnMetadata(row.metadata);
|
|
36415
36621
|
const delivered = providerDelegatedTurn ? {
|
|
@@ -37625,8 +37831,7 @@ async function applySessionTurnSettlement(db, workspaceId, input, hooks = {}) {
|
|
|
37625
37831
|
turnId: input.turnId,
|
|
37626
37832
|
stateVersion: Number(maxVersion) + 1,
|
|
37627
37833
|
serializedRunState: input.runState.serializedRunState,
|
|
37628
|
-
pendingApprovals: input.runState.pendingApprovals
|
|
37629
|
-
frozenCodexCredentialId: input.runState.frozenCodexCredentialId ?? null
|
|
37834
|
+
pendingApprovals: input.runState.pendingApprovals
|
|
37630
37835
|
});
|
|
37631
37836
|
if (humanInputRequests.length > 0) {
|
|
37632
37837
|
for (const request of humanInputRequests) {
|
|
@@ -38426,7 +38631,8 @@ async function requestSessionTurnRecovery(db, workspaceId, input) {
|
|
|
38426
38631
|
}
|
|
38427
38632
|
let providerArtifactsInvalidated = 0;
|
|
38428
38633
|
if (input.providerArtifactInvalidation) {
|
|
38429
|
-
const
|
|
38634
|
+
const historyItemIds = [...new Set(input.providerArtifactInvalidation.historyItemIds)];
|
|
38635
|
+
const invalidatedHistory = historyItemIds.length > 0 ? await tx.update(sessionHistoryItems).set({
|
|
38430
38636
|
providerArtifactInvalidatedAt: now,
|
|
38431
38637
|
providerArtifactInvalidationReason: input.providerArtifactInvalidation.reason,
|
|
38432
38638
|
providerArtifactInvalidatedByAttemptId: input.attemptId
|
|
@@ -38436,35 +38642,37 @@ async function requestSessionTurnRecovery(db, workspaceId, input) {
|
|
|
38436
38642
|
eq18(sessionHistoryItems.workspaceId, workspaceId),
|
|
38437
38643
|
eq18(sessionHistoryItems.sessionId, input.sessionId),
|
|
38438
38644
|
eq18(sessionHistoryItems.active, true),
|
|
38439
|
-
|
|
38440
|
-
sessionHistoryItems.producerCodexCredentialId,
|
|
38441
|
-
input.providerArtifactInvalidation.codexCredentialId
|
|
38442
|
-
),
|
|
38645
|
+
inArray11(sessionHistoryItems.id, historyItemIds),
|
|
38443
38646
|
isNull6(sessionHistoryItems.providerArtifactInvalidatedAt),
|
|
38444
|
-
sql15`${sessionHistoryItems.item} ->> 'type' in ('reasoning', 'compaction')
|
|
38647
|
+
sql15`${sessionHistoryItems.item} ->> 'type' in ('reasoning', 'compaction')`,
|
|
38648
|
+
sql15`(
|
|
38649
|
+
nullif(${sessionHistoryItems.item} ->> 'encrypted_content', '') is not null
|
|
38650
|
+
or nullif(${sessionHistoryItems.item} ->> 'encryptedContent', '') is not null
|
|
38651
|
+
or nullif(${sessionHistoryItems.item} -> 'providerData' ->> 'encrypted_content', '') is not null
|
|
38652
|
+
or nullif(${sessionHistoryItems.item} -> 'providerData' ->> 'encryptedContent', '') is not null
|
|
38653
|
+
)`
|
|
38445
38654
|
)
|
|
38446
|
-
).returning({ id: sessionHistoryItems.id });
|
|
38447
|
-
const
|
|
38448
|
-
and17(
|
|
38449
|
-
eq18(agentRunStates.accountId, session.accountId),
|
|
38450
|
-
eq18(agentRunStates.workspaceId, workspaceId),
|
|
38451
|
-
eq18(agentRunStates.sessionId, input.sessionId),
|
|
38452
|
-
eq18(agentRunStates.turnId, input.turnId),
|
|
38453
|
-
eq18(
|
|
38454
|
-
agentRunStates.frozenCodexCredentialId,
|
|
38455
|
-
input.providerArtifactInvalidation.codexCredentialId
|
|
38456
|
-
),
|
|
38457
|
-
isNull6(agentRunStates.providerArtifactInvalidatedAt)
|
|
38458
|
-
)
|
|
38459
|
-
).orderBy(desc8(agentRunStates.stateVersion)).limit(1);
|
|
38460
|
-
const invalidatedRunState = latestRunState ? await tx.update(agentRunStates).set({
|
|
38655
|
+
).returning({ id: sessionHistoryItems.id }) : [];
|
|
38656
|
+
const invalidatedRunState = input.providerArtifactInvalidation.runStateId ? await tx.update(agentRunStates).set({
|
|
38461
38657
|
providerArtifactInvalidatedAt: now,
|
|
38462
38658
|
providerArtifactInvalidationReason: input.providerArtifactInvalidation.reason,
|
|
38463
38659
|
providerArtifactInvalidatedByAttemptId: input.attemptId
|
|
38464
38660
|
}).where(
|
|
38465
38661
|
and17(
|
|
38466
|
-
eq18(agentRunStates.
|
|
38467
|
-
|
|
38662
|
+
eq18(agentRunStates.accountId, session.accountId),
|
|
38663
|
+
eq18(agentRunStates.workspaceId, workspaceId),
|
|
38664
|
+
eq18(agentRunStates.sessionId, input.sessionId),
|
|
38665
|
+
eq18(agentRunStates.turnId, input.turnId),
|
|
38666
|
+
eq18(agentRunStates.id, input.providerArtifactInvalidation.runStateId),
|
|
38667
|
+
isNull6(agentRunStates.providerArtifactInvalidatedAt),
|
|
38668
|
+
sql15`${agentRunStates.stateVersion} = (
|
|
38669
|
+
select max(latest.state_version)
|
|
38670
|
+
from agent_run_states latest
|
|
38671
|
+
where latest.account_id = ${session.accountId}
|
|
38672
|
+
and latest.workspace_id = ${workspaceId}
|
|
38673
|
+
and latest.session_id = ${input.sessionId}
|
|
38674
|
+
and latest.turn_id = ${input.turnId}
|
|
38675
|
+
)`
|
|
38468
38676
|
)
|
|
38469
38677
|
).returning({ id: agentRunStates.id }) : [];
|
|
38470
38678
|
providerArtifactsInvalidated = invalidatedHistory.length + invalidatedRunState.length;
|
|
@@ -41040,6 +41248,7 @@ export {
|
|
|
41040
41248
|
CODEX_CREDENTIAL_LEASE_TTL_MS,
|
|
41041
41249
|
CODEX_RESET_REDEMPTION_OUTCOMES,
|
|
41042
41250
|
CODEX_ROTATION_STRATEGIES,
|
|
41251
|
+
CodexAppsAuthorizationRevokedError,
|
|
41043
41252
|
ConnectionDisconnectGenerationError,
|
|
41044
41253
|
ConnectionDisconnectIdempotencyError,
|
|
41045
41254
|
ConnectionRefreshHttpError,
|
|
@@ -41244,6 +41453,7 @@ export {
|
|
|
41244
41453
|
claimSlackInteractionProgressDelivery,
|
|
41245
41454
|
claimTerminalRetainedProcesses,
|
|
41246
41455
|
claimWorkspaceArchiveCapture,
|
|
41456
|
+
clearCodexAppsCredential,
|
|
41247
41457
|
clearDurablePendingSessionToolCalls,
|
|
41248
41458
|
clearEnrollmentWentOffline,
|
|
41249
41459
|
clearPendingSessionToolspaceCall,
|
|
@@ -41350,6 +41560,7 @@ export {
|
|
|
41350
41560
|
deleteWorkspaceEnvironmentVariable,
|
|
41351
41561
|
deleteWorkspacePack,
|
|
41352
41562
|
denyDeviceEnrollmentRequest,
|
|
41563
|
+
designateCodexAppsCredential,
|
|
41353
41564
|
diffWorkspaceInstructionPolicyContent,
|
|
41354
41565
|
diffWorkspaceInstructionPolicyRevisions,
|
|
41355
41566
|
disableCapabilityInstallation,
|
|
@@ -41400,6 +41611,8 @@ export {
|
|
|
41400
41611
|
getBillingCustomer,
|
|
41401
41612
|
getCapabilityCatalogItem,
|
|
41402
41613
|
getCapabilityInstallation,
|
|
41614
|
+
getCodexAppsCredentialAuthorizationForRun,
|
|
41615
|
+
getCodexAppsSettings,
|
|
41403
41616
|
getCodexCapacityWaitForSession,
|
|
41404
41617
|
getCodexCredentialStatus,
|
|
41405
41618
|
getCodexResetRedemptionAttempt,
|
|
@@ -41671,7 +41884,6 @@ export {
|
|
|
41671
41884
|
reconcileColdLostLeaseInstanceBlockers,
|
|
41672
41885
|
reconcileSessionAttemptQuiescence,
|
|
41673
41886
|
recordAuditEvent,
|
|
41674
|
-
recordCodexAccountConnectors,
|
|
41675
41887
|
recordCodexAccountUsage,
|
|
41676
41888
|
recordCodexAccountUsageWithWakeTargets,
|
|
41677
41889
|
recordCodexTokenRefresh,
|
|
@@ -41872,6 +42084,7 @@ export {
|
|
|
41872
42084
|
verifyRetainedProcessMutationSettlement,
|
|
41873
42085
|
verifyWorkspaceMutationSettlement,
|
|
41874
42086
|
withAccountRls,
|
|
42087
|
+
withCodexAppsRequestAuthorization,
|
|
41875
42088
|
withCodexCapacityMutation,
|
|
41876
42089
|
withCodexCredentialRefreshLock,
|
|
41877
42090
|
withCodexTokenDeadline,
|