@opengeni/db 0.27.7 → 0.27.9

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.
Files changed (61) hide show
  1. package/dist/{chunk-IHPCI4GV.js → chunk-2JFRTKTG.js} +1 -1
  2. package/dist/chunk-2JFRTKTG.js.map +1 -0
  3. package/dist/{chunk-EX7CDSGH.js → chunk-NX2JNJJP.js} +13 -4
  4. package/dist/chunk-NX2JNJJP.js.map +1 -0
  5. package/dist/codex-token-resolver.d.ts +50 -8
  6. package/dist/connection-token-resolver.d.ts +45 -7
  7. package/dist/database.d.ts +137 -0
  8. package/dist/index.d.ts +25 -154
  9. package/dist/index.js +2796 -2634
  10. package/dist/index.js.map +1 -1
  11. package/dist/insights.d.ts +1 -1
  12. package/dist/memory-governance.d.ts +1 -1
  13. package/dist/new-session-drafts.d.ts +1 -1
  14. package/dist/preference-registry.d.ts +1 -1
  15. package/dist/provision-roles.d.ts +1 -1
  16. package/dist/provision-roles.js +1 -1
  17. package/dist/runtime-posture.d.ts +1 -1
  18. package/dist/schema.d.ts +44 -0
  19. package/dist/schema.js +1 -1
  20. package/dist/scoped-knowledge.d.ts +1 -1
  21. package/dist/session-control.d.ts +2 -1
  22. package/dist/session-queue-commands.d.ts +1 -1
  23. package/dist/session-realtime-context.d.ts +1 -1
  24. package/dist/session-realtime-ledger.d.ts +1 -1
  25. package/dist/session-realtime-mirror.d.ts +1 -1
  26. package/dist/session-realtime-state.d.ts +1 -1
  27. package/dist/session-realtime-terminal.d.ts +1 -1
  28. package/dist/session-realtime.d.ts +1 -1
  29. package/dist/session-tool-call-settlement.d.ts +1 -1
  30. package/dist/turn-initiator.d.ts +1 -1
  31. package/dist/workspace-artifacts.d.ts +1 -1
  32. package/dist/workspace-instruction-policies.d.ts +1 -1
  33. package/drizzle/0170_session_control_wake_revision.sql +133 -0
  34. package/drizzle/0171_social_connection_subject_ownership.sql +53 -0
  35. package/package.json +3 -3
  36. package/src/codex-token-resolver.ts +102 -49
  37. package/src/connection-token-resolver.ts +67 -26
  38. package/src/database.ts +393 -0
  39. package/src/index.ts +439 -516
  40. package/src/insights.ts +2 -2
  41. package/src/memory-governance.ts +2 -2
  42. package/src/new-session-drafts.ts +1 -1
  43. package/src/preference-registry.ts +2 -2
  44. package/src/provision-roles.ts +1 -1
  45. package/src/runtime-posture.ts +1 -1
  46. package/src/schema.ts +16 -3
  47. package/src/scoped-knowledge.ts +2 -2
  48. package/src/session-control.ts +12 -5
  49. package/src/session-queue-commands.ts +4 -1
  50. package/src/session-realtime-context.ts +1 -1
  51. package/src/session-realtime-ledger.ts +1 -1
  52. package/src/session-realtime-mirror.ts +1 -1
  53. package/src/session-realtime-state.ts +1 -1
  54. package/src/session-realtime-terminal.ts +1 -1
  55. package/src/session-realtime.ts +1 -1
  56. package/src/session-tool-call-settlement.ts +1 -1
  57. package/src/turn-initiator.ts +1 -1
  58. package/src/workspace-artifacts.ts +2 -2
  59. package/src/workspace-instruction-policies.ts +2 -2
  60. package/dist/chunk-EX7CDSGH.js.map +0 -1
  61. package/dist/chunk-IHPCI4GV.js.map +0 -1
@@ -1,7 +1,47 @@
1
1
  import { environmentsEncryptionKeyBytes, type Settings } from "@opengeni/config";
2
2
  import { type CodexTokenSnapshot, type CodexUsagePayload, type CodexFetch, type CodexRateLimitResetCreditsDetails, type ResetCreditFetchFailureReason, refreshCodexToken } from "@opengeni/codex";
3
3
  import { encryptEnvironmentValue } from "./environment-crypto";
4
- import { loadCodexCredentialForRun, recordCodexTokenRefresh, setCodexCredentialStatus, withCodexCredentialRefreshLock, type Database } from "./index";
4
+ import type { Database } from "./database";
5
+ export type CodexCredentialTokens = {
6
+ accessToken: string;
7
+ refreshToken: string;
8
+ idToken: string;
9
+ };
10
+ export type CodexCredentialForRun = {
11
+ id: string;
12
+ version: number;
13
+ workspaceId: string;
14
+ tokens: CodexCredentialTokens;
15
+ chatgptAccountId: string | null;
16
+ scopes: string | null;
17
+ planType: string | null;
18
+ isFedramp: boolean;
19
+ expiresAt: Date | null;
20
+ lastRefreshAt: Date | null;
21
+ status: string;
22
+ lastError: string | null;
23
+ };
24
+ export type CodexAccountUsageSnapshot = {
25
+ primaryUsedPercent?: number | null;
26
+ primaryResetAt?: Date | null;
27
+ secondaryUsedPercent?: number | null;
28
+ secondaryResetAt?: Date | null;
29
+ checkedAt?: Date;
30
+ resetCreditAvailableCount?: number | null;
31
+ resetCreditsCheckedAt?: Date | null;
32
+ };
33
+ type CodexCredentialRefreshInput = {
34
+ id: string;
35
+ version: number;
36
+ workspaceId: string;
37
+ credentialEncrypted: string;
38
+ expiresAt: Date | null;
39
+ lastRefreshAt: Date;
40
+ };
41
+ type CodexCredentialStatusTarget = {
42
+ id: string;
43
+ version: number;
44
+ };
5
45
  export type CodexTokenDeadlineClock = {
6
46
  setTimeout: (callback: () => void, delayMs: number) => ReturnType<typeof globalThis.setTimeout>;
7
47
  clearTimeout: (handle: ReturnType<typeof globalThis.setTimeout>) => void;
@@ -19,15 +59,16 @@ export type CodexTokenDeadlineOptions = {
19
59
  */
20
60
  export declare function withCodexTokenDeadline<T>(operation: Promise<T>, options?: CodexTokenDeadlineOptions): Promise<T>;
21
61
  export type CodexAuthDeps = {
22
- loadCredential: typeof loadCodexCredentialForRun;
23
- recordRefresh: typeof recordCodexTokenRefresh;
24
- setStatus: typeof setCodexCredentialStatus;
62
+ loadCredential: (db: Database, settings: Settings, workspaceId: string, credentialId: string) => Promise<CodexCredentialForRun | null>;
63
+ recordRefresh: (db: Database, input: CodexCredentialRefreshInput) => Promise<boolean>;
64
+ setStatus: (db: Database, workspaceId: string, status: "active" | "needs_relogin" | "error", lastError: string | null, target: CodexCredentialStatusTarget) => Promise<boolean>;
25
65
  refresh: typeof refreshCodexToken;
26
66
  encrypt: typeof encryptEnvironmentValue;
27
67
  keyBytes: typeof environmentsEncryptionKeyBytes;
28
- withRefreshLock: typeof withCodexCredentialRefreshLock;
68
+ withRefreshLock: <T>(db: Database, workspaceId: string, credentialId: string, fn: (lockedDb: Database) => Promise<T>) => Promise<T>;
69
+ recordUsage?: (db: Database, workspaceId: string, credentialId: string, snapshot: CodexAccountUsageSnapshot) => Promise<boolean>;
29
70
  };
30
- export declare function buildCodexTokenResolver(db: Database, settings: Settings, workspaceId: string, credentialId: string, deps?: CodexAuthDeps): {
71
+ export declare function buildCodexTokenResolver(db: Database, settings: Settings, workspaceId: string, credentialId: string, deps: CodexAuthDeps): {
31
72
  getToken: () => Promise<CodexTokenSnapshot>;
32
73
  refresh: () => Promise<CodexTokenSnapshot>;
33
74
  };
@@ -45,7 +86,7 @@ export declare function buildCodexTokenResolver(db: Database, settings: Settings
45
86
  * A refresh that stamps needs_relogin returns { status:"error", reason } and never
46
87
  * hits the provider; a transient refresh error returns a plain error payload.
47
88
  */
48
- export declare function fetchCodexUsageForAccount(db: Database, settings: Settings, workspaceId: string, credentialId: string, fetchImpl?: CodexFetch): Promise<CodexUsagePayload>;
89
+ export declare function fetchCodexUsageForAccount(db: Database, settings: Settings, workspaceId: string, credentialId: string, deps: CodexAuthDeps, fetchImpl?: CodexFetch): Promise<CodexUsagePayload>;
49
90
  export type CodexRateLimitResetCreditsAccountResult = {
50
91
  ok: true;
51
92
  status: number;
@@ -61,4 +102,5 @@ export type CodexRateLimitResetCreditsAccountResult = {
61
102
  * this server-side function. Detailed rows are returned to the route only and
62
103
  * are never persisted as redemption authority.
63
104
  */
64
- export declare function fetchCodexRateLimitResetCreditsForAccount(db: Database, settings: Settings, workspaceId: string, credentialId: string, fetchImpl?: CodexFetch): Promise<CodexRateLimitResetCreditsAccountResult>;
105
+ export declare function fetchCodexRateLimitResetCreditsForAccount(db: Database, settings: Settings, workspaceId: string, credentialId: string, deps: CodexAuthDeps, fetchImpl?: CodexFetch): Promise<CodexRateLimitResetCreditsAccountResult>;
106
+ export {};
@@ -1,9 +1,47 @@
1
1
  import { environmentsEncryptionKeyBytes, type McpServerConnectionRef, type Settings } from "@opengeni/config";
2
- import type { ConnectionCredentialsPort, McpConnectionResourceScope, McpCredentialAuthNeededReason, McpCredentialsRequest, TurnInitiator, TurnInitiatorContext } from "@opengeni/contracts";
2
+ import type { ConnectionKind, ConnectionCredentialsPort, ConnectionStatus, McpConnectionResourceScope, McpCredentialAuthNeededReason, McpCredentialsRequest, TurnInitiator, TurnInitiatorContext } from "@opengeni/contracts";
3
3
  import { type DnsLookup, type FetchLike } from "@opengeni/network";
4
4
  export { isPrivateAddress } from "@opengeni/network";
5
5
  import { encryptEnvironmentValue } from "./environment-crypto";
6
- import { loadConnectionCredentialForBroker, recordConnectionTokenRefresh, recordConnectionUsed, setConnectionStatus, type ConnectionCredentialForBroker, type Database } from "./index";
6
+ import type { Database } from "./database";
7
+ export type ConnectionCredentialForBroker = {
8
+ id: string;
9
+ accountId: string;
10
+ workspaceId: string;
11
+ subjectId: string | null;
12
+ providerDomain: string;
13
+ kind: ConnectionKind;
14
+ status: ConnectionStatus;
15
+ credential: Record<string, unknown>;
16
+ grantedScopes: string[];
17
+ expiresAt: Date | null;
18
+ lastRefreshAt: Date | null;
19
+ version: number;
20
+ metadata: Record<string, unknown>;
21
+ };
22
+ export type ConnectionCredentialLookupInput = {
23
+ workspaceId: string;
24
+ connectionId?: string;
25
+ providerDomain: string;
26
+ kind?: ConnectionKind;
27
+ subjectId?: string | null;
28
+ allowSubjectOwned?: boolean;
29
+ };
30
+ export type ConnectionTokenRefreshInput = {
31
+ id: string;
32
+ version: number;
33
+ workspaceId: string;
34
+ credentialEncrypted: string;
35
+ expiresAt: Date | null;
36
+ grantedScopes?: string[];
37
+ lastRefreshAt: Date;
38
+ subjectId?: string | null;
39
+ };
40
+ export type ConnectionStatusGuard = {
41
+ id: string;
42
+ version: number;
43
+ subjectId?: string | null;
44
+ };
7
45
  export type ResolveConnectionCredentialResult = {
8
46
  status: "ok";
9
47
  headers: Record<string, string>;
@@ -60,10 +98,10 @@ export declare class HostMcpCredentialBindingError extends Error {
60
98
  */
61
99
  export declare function buildHostConnectionTokenResolver(resolve: NonNullable<ConnectionCredentialsPort["mcpCredentials"]>, context: HostMcpCredentialResolverContext): (input: ResolveConnectionCredentialInput) => Promise<ResolveConnectionCredentialResult>;
62
100
  export type ConnectionBrokerDeps = {
63
- loadCredential: typeof loadConnectionCredentialForBroker;
64
- recordRefresh: typeof recordConnectionTokenRefresh;
65
- setStatus: typeof setConnectionStatus;
66
- recordUsed: typeof recordConnectionUsed;
101
+ loadCredential: (db: Database, settings: Settings, input: ConnectionCredentialLookupInput) => Promise<ConnectionCredentialForBroker | null>;
102
+ recordRefresh: (db: Database, input: ConnectionTokenRefreshInput) => Promise<boolean>;
103
+ setStatus: (db: Database, workspaceId: string, status: ConnectionStatus, lastError: string | null, guard: ConnectionStatusGuard) => Promise<boolean>;
104
+ recordUsed: (db: Database, workspaceId: string, connectionId: string, subjectId?: string | null) => Promise<void>;
67
105
  refresh: typeof refreshOAuthConnectionCredential;
68
106
  encrypt: typeof encryptEnvironmentValue;
69
107
  keyBytes: typeof environmentsEncryptionKeyBytes;
@@ -92,7 +130,7 @@ export type RefreshTransportOptions = {
92
130
  fetchImpl?: FetchLike;
93
131
  dnsLookup?: DnsLookup;
94
132
  };
95
- export declare function buildConnectionTokenResolver(db: Database, settings: Settings, deps?: ConnectionBrokerDeps, options?: ConnectionTokenResolverOptions): (input: ResolveConnectionCredentialInput) => Promise<ResolveConnectionCredentialResult>;
133
+ export declare function buildConnectionTokenResolver(db: Database, settings: Settings, deps: ConnectionBrokerDeps, options?: ConnectionTokenResolverOptions): (input: ResolveConnectionCredentialInput) => Promise<ResolveConnectionCredentialResult>;
96
134
  export declare class ConnectionRefreshHttpError extends Error {
97
135
  readonly httpStatus: number;
98
136
  readonly oauthErrorCode: string | null;
@@ -0,0 +1,137 @@
1
+ import { type SQL } from "drizzle-orm";
2
+ import type { PgDatabase, PgTransactionConfig } from "drizzle-orm/pg-core";
3
+ import postgres from "postgres";
4
+ import { type IdempotentPersistenceTransactionOptions } from "./persistence-errors";
5
+ import * as schema from "./schema";
6
+ export type Database = PgDatabase<any, typeof schema>;
7
+ export type DbClient = {
8
+ db: Database;
9
+ close: () => Promise<void>;
10
+ };
11
+ export type RlsContext = {
12
+ accountId: string;
13
+ workspaceId?: string | null;
14
+ };
15
+ /**
16
+ * RLS posture for the connection OpenGeni's query layer runs over (Step I, §7.7).
17
+ *
18
+ * - `"force"` (DEFAULT — today's standalone behavior, byte-for-byte): OpenGeni
19
+ * connects as a NON-OWNER role (`opengeni_app`) and every table carries
20
+ * `FORCE ROW LEVEL SECURITY`, so the workspace/account GUCs set by
21
+ * `setRlsContext` are the ONLY thing that admits rows — even the table owner
22
+ * is subject to RLS. This is the Fork-A isolation guarantee.
23
+ * - `"scoped"` (embedded Fork-B opt-in): the host runs OpenGeni's queries over a
24
+ * role that OWNS the dedicated schema (RLS need not be forced for that role),
25
+ * relying on the host's own tenant boundary. OpenGeni STILL emits the
26
+ * `set_config('opengeni.account_id'/'workspace_id', …)` GUCs defensively on
27
+ * every scoped query, so the application query path is byte-identical between
28
+ * the two strategies and the app code is RLS-mode-agnostic. The strategy is a
29
+ * declared posture (consumed by `provisionRoles` and as a documented
30
+ * invariant), NOT a query-path branch — there is deliberately no `if
31
+ * (strategy === …)` anywhere in the helpers below. Picking `"scoped"` does not
32
+ * relax any GUC; it only changes which DB role the host provisions/connects as
33
+ * and asserts that the host accepts owning the isolation boundary.
34
+ */
35
+ export type RlsStrategy = "force" | "scoped";
36
+ /**
37
+ * Resolve a host-IdP/Better-Auth user *identifier* by email. Injected via
38
+ * `createDb({ userLookup })` (Step I). UNSET → today's raw parameterized select
39
+ * against Better Auth's `auth_users` table (see `getManagedUserByEmail`), which
40
+ * relies on the postgres-js array-shaped `db.execute` result. An embedded host
41
+ * whose identity lives elsewhere (a different IdP table, a different driver, or
42
+ * a non-`auth_users` user store) injects this closure so OpenGeni never touches
43
+ * `auth_users` directly. Returns the user id, or null when no such user exists.
44
+ */
45
+ export type UserLookup = (db: Database, email: string) => Promise<string | null>;
46
+ export type CreateDbOptions = {
47
+ /**
48
+ * The Postgres `search_path` for this connection (Step I, §7.8 runtime half).
49
+ * UNSET → today's behavior: NO `search_path` startup parameter is sent, so the
50
+ * server default applies (`public` for standalone, where every table + the
51
+ * `vector` extension + `gen_random_uuid()` live). For an embedded dedicated
52
+ * schema, pass e.g. `"opengeni,opengeni_private,public"` — postgres-js sends
53
+ * it as a per-session startup parameter (the supported, query-param-free way;
54
+ * URL `?search_path=` is IGNORED by postgres-js). Keep `public` LAST so the
55
+ * `vector` type and `gen_random_uuid()` (which live in `public` on the
56
+ * pgvector image) still resolve — the schema-isolation contract live footgun.
57
+ */
58
+ searchPath?: string;
59
+ /** RLS posture; defaults to `"force"` (today's standalone). */
60
+ rlsStrategy?: RlsStrategy;
61
+ /** Host-provided user-by-email resolver; unset → today's raw `auth_users` query. */
62
+ userLookup?: UserLookup;
63
+ /** postgres-js pool size; defaults to today's `10`. */
64
+ max?: number;
65
+ /**
66
+ * Connection-local default transaction isolation sent in the postgres-js
67
+ * startup parameters. This is intentionally not a role/database default:
68
+ * tests and embedded callers can exercise a different ambient isolation
69
+ * without mutating a shared PostgreSQL role or affecting other connections.
70
+ */
71
+ isolationLevel?: postgres.ConnectionParameters["default_transaction_isolation"];
72
+ };
73
+ /**
74
+ * The active RLS strategy + userLookup for an injected `Database`, recorded in a
75
+ * side WeakMap so helpers (and `getManagedUserByEmail`) can consult the host's
76
+ * binding without changing every call signature. A handle with no recorded
77
+ * config (e.g. one built outside `createDb`, or in a test) falls back to the
78
+ * standalone defaults: `rlsStrategy: "force"`, raw `auth_users` lookup.
79
+ */
80
+ type DbBinding = {
81
+ rlsStrategy: RlsStrategy;
82
+ userLookup?: UserLookup;
83
+ };
84
+ /** The strategy bound to a handle (or the `"force"` default). */
85
+ export declare function rlsStrategyFor(db: Database): RlsStrategy;
86
+ /**
87
+ * Run a raw SQL query and read its rows as a typed array.
88
+ *
89
+ * Why this exists: the Step I driver widening (`Database = PgDatabase<any, …>`)
90
+ * deliberately sets the query-result HKT to `any` so `db.execute(…)` is callable
91
+ * across drivers whose raw-result shapes differ (postgres-js → row array;
92
+ * node-postgres → `{ rows }`). A side effect is that `db.execute<T>(…)` now
93
+ * resolves to `any`, erasing the per-row element type at the call site. OpenGeni's
94
+ * OWN internal raw queries usually run over the postgres-js handle `createDb`
95
+ * builds (array result), while an embedded host may inject a node-postgres style
96
+ * driver (`{ rows }`). Normalize those two standard shapes in one place; reject
97
+ * an unknown driver result rather than silently treating it as an empty query.
98
+ */
99
+ export declare function rawRows<T extends Record<string, unknown>>(executor: Pick<Database, "execute">, query: SQL): Promise<T[]>;
100
+ export declare function createDb(databaseUrl: string, options?: CreateDbOptions): DbClient;
101
+ /**
102
+ * Register a host's `rlsStrategy`/`userLookup` against an externally-constructed
103
+ * `Database` handle (e.g. one the embedded host built from its own driver and
104
+ * injected, rather than via `createDb`). Lets the same WeakMap-backed lookups
105
+ * work for injected handles. Standalone never calls this (it uses `createDb`).
106
+ */
107
+ export declare function registerDbBinding(db: Database, binding: {
108
+ rlsStrategy?: RlsStrategy;
109
+ userLookup?: UserLookup;
110
+ }): void;
111
+ export declare function setRlsContext(db: Database, context: RlsContext): Promise<void>;
112
+ export declare function withRlsContext<T>(db: Database, context: RlsContext, fn: (db: Database) => Promise<T>, transactionConfig?: PgTransactionConfig): Promise<T>;
113
+ /**
114
+ * Run one bounded database operation on a transaction-pinned backend.
115
+ *
116
+ * Callers that also have an application deadline should check their abort
117
+ * signal before returning from `fn`; throwing there rolls the transaction back
118
+ * even when the application deadline won a surrounding Promise race.
119
+ */
120
+ export declare function withDatabaseStatementTimeout<T>(db: Database, timeoutMs: number, fn: (db: Database) => Promise<T>): Promise<T>;
121
+ export declare function rlsContextForWorkspace(db: Database, workspaceId: string): Promise<RlsContext>;
122
+ export declare function withWorkspaceRls<T>(db: Database, workspaceId: string, fn: (db: Database) => Promise<T>): Promise<T>;
123
+ export declare function retryWorkspacePersistence<T>(db: Database, workspaceId: string, options: IdempotentPersistenceTransactionOptions, fn: (db: Database) => Promise<T>): Promise<T>;
124
+ export declare function retryRlsPersistence<T>(db: Database, context: RlsContext, options: IdempotentPersistenceTransactionOptions, fn: (db: Database) => Promise<T>): Promise<T>;
125
+ /**
126
+ * Personal workspace data needs both tenant and authenticated-principal GUCs.
127
+ * `session_pins` uses this helper so FORCE RLS rejects another member's rows
128
+ * even if a future query accidentally omits its explicit subject predicate.
129
+ */
130
+ export declare function withWorkspaceSubjectRls<T>(db: Database, workspaceId: string, subjectId: string, fn: (db: Database) => Promise<T>, transactionConfig?: PgTransactionConfig): Promise<T>;
131
+ /** Apply and verify actor-private RLS on an already transaction-pinned handle. */
132
+ export declare function setSubjectRlsContext(db: Database, subjectId: string): Promise<void>;
133
+ export declare function withWorkspaceUsageLock<T>(db: Database, workspaceId: string, fn: (db: Database) => Promise<T>): Promise<T>;
134
+ export declare function withAccountRls<T>(db: Database, accountId: string, fn: (db: Database) => Promise<T>): Promise<T>;
135
+ /** Internal lookup for the host binding attached to a database handle. */
136
+ export declare function dbBindingFor(db: Database): DbBinding | undefined;
137
+ export {};
package/dist/index.d.ts CHANGED
@@ -1,11 +1,10 @@
1
1
  import type { AccessContext, AccessGrant, AccessPrincipalKind, ApiKey, BillingBalance, CapabilityCatalogItem, CapabilityInstallation, CapabilityKind, CapabilityPack, CapabilitySource, ConnectionKind, ConnectionMetadata, ConnectionStatus, DocumentAuthorityKind, McpServerConnectionRef, FileAsset, FileUploadStatus, FirstPartyMcpToolName, HumanInputQuestion, HumanInputResponse, KnowledgeMemory, KnowledgeMemoryKind, KnowledgeMemoryStatus, KnowledgeSourceRef, GitHubInstallationAuthorityKind, GitHubRepositoryScope, HostEventExportBatch, HostUsageExportBatch, ManagedAccount, McpPersonalConnectionDelegation, Permission, PackInstallation, PackInstallationStatus, ResourceRef, SandboxBackend, SandboxOs, ScheduledTask, ScheduledTaskAgentConfig, ScheduledTaskOverlapPolicy, ScheduledTaskRun, ScheduledTaskRunMode, ScheduledTaskRunStatus, ScheduledTaskScheduleSpec, ScheduledTaskStatus, ScheduledTaskTriggerType, Session, SessionAuthorizationListScope, SessionListResponse, SessionEvent, SessionEventPayloadMode, SessionEventReadDirection, SessionEventSemanticClass, SessionEventType, SessionGoal, SessionGoalCreatedBy, SessionGoalStatus, SessionHumanInputRequest, LineageNode, SessionMcpApprovalPolicy, SessionSkill, SessionMcpServerMetadata, SessionStatus, SessionToolPolicy, SessionTurn, SessionQueueSnapshot, SessionSystemUpdate, SessionSystemUpdateKind, SystemUpdateClassification, SessionTurnSource, SessionTurnStatus, TurnInitiator, TurnInitiatorContext, SocialConnection, SocialConnectionStatus, SocialPost, SocialProvider, ToolRef, ReasoningEffort, UsageEvent, Workspace, WorkspaceControlEvent, VariableSet, VariableSetVariableMetadata, WorkspaceMember, WorkspaceRegisteredPack, Rig, RigVersion, RigChange, RigChangeKind, RigChangeStatus, RigCheck, NativeSnapshotDescriptor, TarWorkspaceArchiveDescriptor, WorkspaceArchiveDescriptor, ModalCheckpointProviderBinding } from "@opengeni/contracts";
2
2
  import { type LatencyMode, SessionSystemUpdatePayload, TurnExecutionPolicyV1 } from "@opengeni/contracts";
3
3
  import { type Settings } from "@opengeni/config";
4
+ import { type CodexFetch } from "@opengeni/codex";
4
5
  export { isCodexBilledModel } from "@opengeni/codex";
5
6
  import { type SQL } from "drizzle-orm";
6
7
  export { frozenInitiatorForCommandActor, type FrozenTurnInitiator } from "./turn-initiator";
7
- import type { PgDatabase, PgTransactionConfig } from "drizzle-orm/pg-core";
8
- import postgres from "postgres";
9
8
  import { type SessionDiscoveryControl, type SessionCommandActor, type SessionTurnAttemptOutcome } from "./session-control";
10
9
  import { type SessionRealtimeContinuityEntry } from "./session-realtime-context";
11
10
  import * as schema from "./schema";
@@ -31,21 +30,16 @@ export { sanitizeMemoryText } from "./memory-domain";
31
30
  export { migrate, runMigrations } from "./migrate";
32
31
  export { provisionRoles, type ProvisionResult, type ProvisionRolesOptions, } from "./provision-roles";
33
32
  export * from "./memory-domain";
34
- export type Database = PgDatabase<any, typeof schema>;
33
+ import { type Database } from "./database";
34
+ export { createDb, registerDbBinding, rlsContextForWorkspace, rlsStrategyFor, setRlsContext, setSubjectRlsContext, withAccountRls, withDatabaseStatementTimeout, withRlsContext, withWorkspaceRls, withWorkspaceSubjectRls, withWorkspaceUsageLock, type CreateDbOptions, type Database, type DbClient, type RlsContext, type RlsStrategy, type UserLookup, } from "./database";
35
+ import { buildCodexTokenResolver as buildCodexTokenResolverCore, fetchCodexRateLimitResetCreditsForAccount as fetchCodexRateLimitResetCreditsForAccountCore, fetchCodexUsageForAccount as fetchCodexUsageForAccountCore, type CodexAccountUsageSnapshot, type CodexAuthDeps, type CodexCredentialForRun } from "./codex-token-resolver";
36
+ import { buildConnectionTokenResolver as buildConnectionTokenResolverCore, type ConnectionBrokerDeps, type ConnectionCredentialForBroker, type ConnectionTokenResolverOptions } from "./connection-token-resolver";
35
37
  /** Raised when a durable session tool-policy write lost its version fence. */
36
38
  export declare class SessionToolPolicyVersionConflictError extends Error {
37
39
  readonly currentVersion: number;
38
40
  readonly code = "SESSION_TOOL_POLICY_CONFLICT";
39
41
  constructor(currentVersion: number);
40
42
  }
41
- export type DbClient = {
42
- db: Database;
43
- close: () => Promise<void>;
44
- };
45
- export type RlsContext = {
46
- accountId: string;
47
- workspaceId?: string | null;
48
- };
49
43
  export type NestedAgentDepthPolicySource = "session" | "workspace" | "deployment" | "default";
50
44
  export type SessionDepthPolicy = {
51
45
  rootSessionId: string;
@@ -94,77 +88,6 @@ export declare class SessionSpawnDeniedDbError extends Error {
94
88
  readonly denial: SessionSpawnDenial;
95
89
  constructor(denial: SessionSpawnDenial);
96
90
  }
97
- /**
98
- * RLS posture for the connection OpenGeni's query layer runs over (Step I, §7.7).
99
- *
100
- * - `"force"` (DEFAULT — today's standalone behavior, byte-for-byte): OpenGeni
101
- * connects as a NON-OWNER role (`opengeni_app`) and every table carries
102
- * `FORCE ROW LEVEL SECURITY`, so the workspace/account GUCs set by
103
- * `setRlsContext` are the ONLY thing that admits rows — even the table owner
104
- * is subject to RLS. This is the Fork-A isolation guarantee.
105
- * - `"scoped"` (embedded Fork-B opt-in): the host runs OpenGeni's queries over a
106
- * role that OWNS the dedicated schema (RLS need not be forced for that role),
107
- * relying on the host's own tenant boundary. OpenGeni STILL emits the
108
- * `set_config('opengeni.account_id'/'workspace_id', …)` GUCs defensively on
109
- * every scoped query, so the application query path is byte-identical between
110
- * the two strategies and the app code is RLS-mode-agnostic. The strategy is a
111
- * declared posture (consumed by `provisionRoles` and as a documented
112
- * invariant), NOT a query-path branch — there is deliberately no `if
113
- * (strategy === …)` anywhere in the helpers below. Picking `"scoped"` does not
114
- * relax any GUC; it only changes which DB role the host provisions/connects as
115
- * and asserts that the host accepts owning the isolation boundary.
116
- */
117
- export type RlsStrategy = "force" | "scoped";
118
- /**
119
- * Resolve a host-IdP/Better-Auth user *identifier* by email. Injected via
120
- * `createDb({ userLookup })` (Step I). UNSET → today's raw parameterized select
121
- * against Better Auth's `auth_users` table (see `getManagedUserByEmail`), which
122
- * relies on the postgres-js array-shaped `db.execute` result. An embedded host
123
- * whose identity lives elsewhere (a different IdP table, a different driver, or
124
- * a non-`auth_users` user store) injects this closure so OpenGeni never touches
125
- * `auth_users` directly. Returns the user id, or null when no such user exists.
126
- */
127
- export type UserLookup = (db: Database, email: string) => Promise<string | null>;
128
- export type CreateDbOptions = {
129
- /**
130
- * The Postgres `search_path` for this connection (Step I, §7.8 runtime half).
131
- * UNSET → today's behavior: NO `search_path` startup parameter is sent, so the
132
- * server default applies (`public` for standalone, where every table + the
133
- * `vector` extension + `gen_random_uuid()` live). For an embedded dedicated
134
- * schema, pass e.g. `"opengeni,opengeni_private,public"` — postgres-js sends
135
- * it as a per-session startup parameter (the supported, query-param-free way;
136
- * URL `?search_path=` is IGNORED by postgres-js). Keep `public` LAST so the
137
- * `vector` type and `gen_random_uuid()` (which live in `public` on the
138
- * pgvector image) still resolve — the schema-isolation contract live footgun.
139
- */
140
- searchPath?: string;
141
- /** RLS posture; defaults to `"force"` (today's standalone). */
142
- rlsStrategy?: RlsStrategy;
143
- /** Host-provided user-by-email resolver; unset → today's raw `auth_users` query. */
144
- userLookup?: UserLookup;
145
- /** postgres-js pool size; defaults to today's `10`. */
146
- max?: number;
147
- /**
148
- * Connection-local default transaction isolation sent in the postgres-js
149
- * startup parameters. This is intentionally not a role/database default:
150
- * tests and embedded callers can exercise a different ambient isolation
151
- * without mutating a shared PostgreSQL role or affecting other connections.
152
- */
153
- isolationLevel?: postgres.ConnectionParameters["default_transaction_isolation"];
154
- };
155
- /** The strategy bound to a handle (or the `"force"` default). */
156
- export declare function rlsStrategyFor(db: Database): RlsStrategy;
157
- export declare function createDb(databaseUrl: string, options?: CreateDbOptions): DbClient;
158
- /**
159
- * Register a host's `rlsStrategy`/`userLookup` against an externally-constructed
160
- * `Database` handle (e.g. one the embedded host built from its own driver and
161
- * injected, rather than via `createDb`). Lets the same WeakMap-backed lookups
162
- * work for injected handles. Standalone never calls this (it uses `createDb`).
163
- */
164
- export declare function registerDbBinding(db: Database, binding: {
165
- rlsStrategy?: RlsStrategy;
166
- userLookup?: UserLookup;
167
- }): void;
168
91
  export type HostExportKind = "session_event" | "usage_event";
169
92
  /**
170
93
  * A leased row did not satisfy this consumer build's export contract. Only
@@ -274,27 +197,6 @@ export declare function getHostExportConsumerStatus(db: Database, input: {
274
197
  kind: HostExportKind;
275
198
  consumerId: string;
276
199
  }): Promise<HostExportConsumerStatus | null>;
277
- export declare function setRlsContext(db: Database, context: RlsContext): Promise<void>;
278
- export declare function withRlsContext<T>(db: Database, context: RlsContext, fn: (db: Database) => Promise<T>, transactionConfig?: PgTransactionConfig): Promise<T>;
279
- /**
280
- * Run one bounded database operation on a transaction-pinned backend.
281
- *
282
- * Callers that also have an application deadline should check their abort
283
- * signal before returning from `fn`; throwing there rolls the transaction back
284
- * even when the application deadline won a surrounding Promise race.
285
- */
286
- export declare function withDatabaseStatementTimeout<T>(db: Database, timeoutMs: number, fn: (db: Database) => Promise<T>): Promise<T>;
287
- export declare function rlsContextForWorkspace(db: Database, workspaceId: string): Promise<RlsContext>;
288
- export declare function withWorkspaceRls<T>(db: Database, workspaceId: string, fn: (db: Database) => Promise<T>): Promise<T>;
289
- /**
290
- * Personal workspace data needs both tenant and authenticated-principal GUCs.
291
- * `session_pins` uses this helper so FORCE RLS rejects another member's rows
292
- * even if a future query accidentally omits its explicit subject predicate.
293
- */
294
- export declare function withWorkspaceSubjectRls<T>(db: Database, workspaceId: string, subjectId: string, fn: (db: Database) => Promise<T>, transactionConfig?: PgTransactionConfig): Promise<T>;
295
- /** Apply and verify actor-private RLS on an already transaction-pinned handle. */
296
- export declare function setSubjectRlsContext(db: Database, subjectId: string): Promise<void>;
297
- export declare function withWorkspaceUsageLock<T>(db: Database, workspaceId: string, fn: (db: Database) => Promise<T>): Promise<T>;
298
200
  export type DocumentIndexAuthority = {
299
201
  authorityKind: DocumentAuthorityKind;
300
202
  authorityWorkspaceId: string | null;
@@ -313,7 +215,6 @@ export declare function resolveDocumentIndexAuthority(db: Database, input: {
313
215
  workspaceId: string;
314
216
  documentId: string;
315
217
  }): Promise<DocumentIndexAuthority | null>;
316
- export declare function withAccountRls<T>(db: Database, accountId: string, fn: (db: Database) => Promise<T>): Promise<T>;
317
218
  export declare const allWorkspacePermissions: Permission[];
318
219
  export declare const allAccountPermissions: Permission[];
319
220
  export type BootstrapWorkspaceInput = {
@@ -710,6 +611,7 @@ export type WorkspaceStateMemoryRecord = {
710
611
  export type CreateSocialConnectionInput = {
711
612
  accountId: string;
712
613
  workspaceId: string;
614
+ subjectId?: string | null;
713
615
  provider: SocialProvider;
714
616
  accountHandle: string;
715
617
  accountName?: string | null;
@@ -724,6 +626,7 @@ export type CreateSocialConnectionInput = {
724
626
  export type UpsertSocialOAuthConnectionInput = {
725
627
  accountId: string;
726
628
  workspaceId: string;
629
+ subjectId?: string | null;
727
630
  provider: SocialProvider;
728
631
  accountHandle: string;
729
632
  accountName?: string | null;
@@ -735,6 +638,7 @@ export type UpsertSocialOAuthConnectionInput = {
735
638
  export type UpdateSocialConnectionCredentialInput = {
736
639
  workspaceId: string;
737
640
  connectionId: string;
641
+ subjectId?: string | null;
738
642
  credentialEncrypted?: string | null;
739
643
  status?: SocialConnectionStatus;
740
644
  tokenMetadata?: Record<string, unknown>;
@@ -742,6 +646,7 @@ export type UpdateSocialConnectionCredentialInput = {
742
646
  export type CreateSocialPostInput = {
743
647
  accountId: string;
744
648
  workspaceId: string;
649
+ subjectId?: string | null;
745
650
  connectionId: string;
746
651
  externalPostId?: string | null;
747
652
  url?: string | null;
@@ -862,21 +767,6 @@ export type SlackBotDeleteOperation = {
862
767
  createdAt: Date;
863
768
  updatedAt: Date;
864
769
  };
865
- export type ConnectionCredentialForBroker = {
866
- id: string;
867
- accountId: string;
868
- workspaceId: string;
869
- subjectId: string | null;
870
- providerDomain: string;
871
- kind: ConnectionKind;
872
- status: ConnectionStatus;
873
- credential: Record<string, unknown>;
874
- grantedScopes: string[];
875
- expiresAt: Date | null;
876
- lastRefreshAt: Date | null;
877
- version: number;
878
- metadata: Record<string, unknown>;
879
- };
880
770
  export type IntegrationOAuthClientForUse = {
881
771
  id: string;
882
772
  issuer: string;
@@ -1681,14 +1571,14 @@ export declare function upsertSocialOAuthConnection(db: Database, input: UpsertS
1681
1571
  * of mapSocialConnection so the encrypted bundle never rides along on list or
1682
1572
  * MCP responses.
1683
1573
  */
1684
- export declare function loadSocialConnectionCredential(db: Database, workspaceId: string, connectionId: string): Promise<{
1574
+ export declare function loadSocialConnectionCredential(db: Database, workspaceId: string, connectionId: string, subjectId?: string | null): Promise<{
1685
1575
  connection: SocialConnection;
1686
1576
  credentialEncrypted: string | null;
1687
1577
  } | null>;
1688
1578
  export declare function updateSocialConnectionCredential(db: Database, input: UpdateSocialConnectionCredentialInput): Promise<SocialConnection | null>;
1689
- export declare function listSocialConnections(db: Database, workspaceId: string, limit?: number): Promise<SocialConnection[]>;
1690
- export declare function getSocialConnection(db: Database, workspaceId: string, connectionId: string): Promise<SocialConnection | null>;
1691
- export declare function requireSocialConnection(db: Database, workspaceId: string, connectionId: string): Promise<SocialConnection>;
1579
+ export declare function listSocialConnections(db: Database, workspaceId: string, limit?: number, subjectId?: string | null): Promise<SocialConnection[]>;
1580
+ export declare function getSocialConnection(db: Database, workspaceId: string, connectionId: string, subjectId?: string | null): Promise<SocialConnection | null>;
1581
+ export declare function requireSocialConnection(db: Database, workspaceId: string, connectionId: string, subjectId?: string | null): Promise<SocialConnection>;
1692
1582
  export declare function createSocialPost(db: Database, input: CreateSocialPostInput): Promise<SocialPost>;
1693
1583
  /**
1694
1584
  * Idempotent bulk ingest for provider sync: rows already present under the
@@ -1699,6 +1589,7 @@ export declare function recordSyncedSocialPosts(db: Database, input: {
1699
1589
  accountId: string;
1700
1590
  workspaceId: string;
1701
1591
  connectionId: string;
1592
+ subjectId?: string | null;
1702
1593
  posts: Array<{
1703
1594
  externalPostId: string;
1704
1595
  url?: string | null;
@@ -1714,6 +1605,7 @@ export declare function recordSyncedSocialPosts(db: Database, input: {
1714
1605
  }>;
1715
1606
  export declare function listSocialPosts(db: Database, options: {
1716
1607
  workspaceId: string;
1608
+ subjectId?: string | null;
1717
1609
  connectionIds?: string[];
1718
1610
  since?: Date;
1719
1611
  limit?: number;
@@ -1970,25 +1862,6 @@ export declare function loadVariableSetForRun(db: Database, settings: Settings,
1970
1862
  export declare const loadWorkspaceEnvironmentForRun: typeof loadVariableSetForRun;
1971
1863
  /** @deprecated use VariableSetForRun */
1972
1864
  export type WorkspaceEnvironmentForRun = VariableSetForRun;
1973
- export type CodexCredentialTokens = {
1974
- accessToken: string;
1975
- refreshToken: string;
1976
- idToken: string;
1977
- };
1978
- export type CodexCredentialForRun = {
1979
- id: string;
1980
- version: number;
1981
- workspaceId: string;
1982
- tokens: CodexCredentialTokens;
1983
- chatgptAccountId: string | null;
1984
- scopes: string | null;
1985
- planType: string | null;
1986
- isFedramp: boolean;
1987
- expiresAt: Date | null;
1988
- lastRefreshAt: Date | null;
1989
- status: string;
1990
- lastError: string | null;
1991
- };
1992
1865
  /**
1993
1866
  * Login / rotation write (multi-account P1). Caller passes the PRE-encrypted
1994
1867
  * credential blob. Keyed on the composite partial index (workspace, chatgpt
@@ -2664,16 +2537,6 @@ export declare function completeCodexResetRedemption(db: Database, input: {
2664
2537
  outcome: CodexResetRedemptionOutcome;
2665
2538
  }): Promise<CodexCapacityMutationResult<CodexResetRedemptionAttempt | null>>;
2666
2539
  /** The P2 usage-cache snapshot written by the refreshing usage wrapper. */
2667
- export type CodexAccountUsageSnapshot = {
2668
- primaryUsedPercent?: number | null;
2669
- primaryResetAt?: Date | null;
2670
- secondaryUsedPercent?: number | null;
2671
- secondaryResetAt?: Date | null;
2672
- /** Present only when the quota body parsed successfully. */
2673
- checkedAt?: Date;
2674
- resetCreditAvailableCount?: number | null;
2675
- resetCreditsCheckedAt?: Date | null;
2676
- };
2677
2540
  /**
2678
2541
  * Cache-write for P2 quota bars: persist the five plaintext usage columns on a
2679
2542
  * SPECIFIC credential row. NEVER touches credential_encrypted. RLS-scoped, guarded
@@ -6375,6 +6238,7 @@ export type RequestSessionTurnRecoveryInput = {
6375
6238
  attemptId: string;
6376
6239
  reason: string;
6377
6240
  detail?: Record<string, unknown>;
6241
+ providerRecoveryCount?: number;
6378
6242
  fromStatuses?: SessionTurnStatus[];
6379
6243
  providerArtifactInvalidation?: {
6380
6244
  codexCredentialId: string;
@@ -6501,6 +6365,7 @@ export declare function enqueueSessionWorkflowWakeInTransaction(tx: Database, in
6501
6365
  temporalWorkflowId: string;
6502
6366
  reason: string;
6503
6367
  notBefore?: Date;
6368
+ controlRequested?: boolean;
6504
6369
  }): Promise<number>;
6505
6370
  /** Standalone transactional producer for operations not already in a DB txn. */
6506
6371
  export declare function enqueueSessionWorkflowWake(db: Database, input: {
@@ -6510,6 +6375,7 @@ export declare function enqueueSessionWorkflowWake(db: Database, input: {
6510
6375
  temporalWorkflowId: string;
6511
6376
  reason: string;
6512
6377
  notBefore?: Date;
6378
+ controlRequested?: boolean;
6513
6379
  }): Promise<number>;
6514
6380
  /**
6515
6381
  * Re-deliver already-committed session work only when admission currently
@@ -6523,6 +6389,7 @@ export declare function enqueueSessionWorkflowWakeIfRunnable(db: Database, input
6523
6389
  temporalWorkflowId: string;
6524
6390
  reason: string;
6525
6391
  notBefore?: Date;
6392
+ controlRequested?: boolean;
6526
6393
  }): Promise<number | null>;
6527
6394
  /** Claim only explicit, undelivered wake revisions; never infer work by scan. */
6528
6395
  export declare function claimPendingSessionWorkflowWakes(db: Database, limit?: number): Promise<SessionWorkflowWake[]>;
@@ -6662,6 +6529,10 @@ export declare function appendSessionEventsWithLockedSessionUpdate(db: Database,
6662
6529
  lockParentSession?: boolean;
6663
6530
  }): Promise<SessionEvent[]>;
6664
6531
  export declare function sessionSubject(workspaceId: string, sessionId: string): string;
6665
- export * from "./codex-token-resolver";
6666
- export * from "./connection-token-resolver";
6532
+ export declare function buildCodexTokenResolver(db: Database, settings: Settings, workspaceId: string, credentialId: string, deps?: CodexAuthDeps): ReturnType<typeof buildCodexTokenResolverCore>;
6533
+ export declare function fetchCodexUsageForAccount(db: Database, settings: Settings, workspaceId: string, credentialId: string, fetchImpl?: CodexFetch): ReturnType<typeof fetchCodexUsageForAccountCore>;
6534
+ export declare function fetchCodexRateLimitResetCreditsForAccount(db: Database, settings: Settings, workspaceId: string, credentialId: string, fetchImpl?: CodexFetch): ReturnType<typeof fetchCodexRateLimitResetCreditsForAccountCore>;
6535
+ export declare function buildConnectionTokenResolver(db: Database, settings: Settings, deps?: ConnectionBrokerDeps, options?: ConnectionTokenResolverOptions): ReturnType<typeof buildConnectionTokenResolverCore>;
6536
+ export { withCodexTokenDeadline, type CodexAccountUsageSnapshot, type CodexAuthDeps, type CodexCredentialForRun, type CodexCredentialTokens, type CodexRateLimitResetCreditsAccountResult, type CodexTokenDeadlineClock, type CodexTokenDeadlineOptions, } from "./codex-token-resolver";
6537
+ export { buildHostConnectionTokenResolver, ConnectionRefreshHttpError, HostMcpCredentialBindingError, HostMcpCredentialScopeError, isPrivateAddress, normalizeBearerScheme, refreshOAuthConnectionCredential, type ConnectionBrokerDeps, type ConnectionCredentialForBroker, type ConnectionCredentialLookupInput, type ConnectionStatusGuard, type ConnectionTokenRefreshInput, type ConnectionTokenResolverOptions, type HostMcpCredentialResolverContext, type PermanentConnectionRefreshFailure, type RefreshTransportOptions, type ResolveConnectionCredentialInput, type ResolveConnectionCredentialResult, } from "./connection-token-resolver";
6667
6538
  export * from "./workspace-artifacts";