@opengeni/core 3.0.1 → 3.1.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/README.md +4 -4
- package/dist/access/index.d.ts +131 -7
- package/dist/access/service-initiator.d.ts +3 -0
- package/dist/application/archived-session-imports.d.ts +6 -0
- package/dist/application/composer-submit.d.ts +1 -1
- package/dist/application/connect-operation.d.ts +6 -0
- package/dist/application/external-workspace-members.d.ts +13 -1
- package/dist/application/modal-native-live-declaration-join.d.ts +37 -0
- package/dist/application/modal-native-original-configuration.d.ts +79 -0
- package/dist/application/modal-native-worker-host-transport.d.ts +297 -0
- package/dist/application/new-session-drafts.d.ts +29 -2
- package/dist/application/organization-privacy.d.ts +57 -0
- package/dist/application/prepared-mcp-connection.d.ts +31 -0
- package/dist/application/sandbox-recovery.d.ts +58 -0
- package/dist/application/session-commands.d.ts +3 -0
- package/dist/application/session-tenancy.d.ts +13 -4
- package/dist/billing/agent-run-admission.d.ts +21 -0
- package/dist/billing/limits.d.ts +27 -1
- package/dist/billing/model-call-admission.d.ts +34 -0
- package/dist/billing/model-usage-settlement.d.ts +112 -0
- package/dist/canonical-human-identities.js +1 -1
- package/dist/{chunk-VCZFFEPB.js → chunk-7T2SZ7BI.js} +16 -2
- package/dist/chunk-7T2SZ7BI.js.map +1 -0
- package/dist/{chunk-ZYCNLYGH.js → chunk-OMJFIIWK.js} +178 -12
- package/dist/chunk-OMJFIIWK.js.map +1 -0
- package/dist/{chunk-H7X52RI2.js → chunk-QI2M2B2K.js} +83 -8
- package/dist/chunk-QI2M2B2K.js.map +1 -0
- package/dist/{chunk-OF65T3PM.js → chunk-TTWTXQB2.js} +94 -6
- package/dist/chunk-TTWTXQB2.js.map +1 -0
- package/dist/codex-model-availability.d.ts +55 -0
- package/dist/default-session-model.d.ts +192 -0
- package/dist/dependencies.d.ts +41 -7
- package/dist/developer-setup-credential-ceiling.d.ts +10 -0
- package/dist/domain/agent-config-resolution.d.ts +49 -0
- package/dist/domain/automations.d.ts +8 -1
- package/dist/domain/capabilities.d.ts +112 -8
- package/dist/domain/connection-account-selection-error.d.ts +8 -0
- package/dist/domain/connector-tool-permissions.d.ts +62 -0
- package/dist/domain/direct-model-provider.d.ts +3 -0
- package/dist/domain/editable-artifacts/agent-application.d.ts +10 -1
- package/dist/domain/editable-artifacts/durable-export.d.ts +22 -1
- package/dist/domain/editable-artifacts/ports.d.ts +10 -0
- package/dist/domain/editable-artifacts/service.d.ts +3 -1
- package/dist/domain/editable-artifacts/types.d.ts +1 -1
- package/dist/domain/encryption-key.d.ts +12 -0
- package/dist/domain/insights-timing.d.ts +16 -0
- package/dist/domain/insights-usage.d.ts +27 -0
- package/dist/domain/insights.d.ts +21 -3
- package/dist/domain/knowledge-files.d.ts +1 -1
- package/dist/domain/knowledge-preparation.d.ts +10 -0
- package/dist/domain/knowledge-preparation.test.d.ts +1 -0
- package/dist/domain/knowledge-search.d.ts +15 -76
- package/dist/domain/mcp-account-bindings.d.ts +17 -0
- package/dist/domain/mcp-account-routes.d.ts +21 -0
- package/dist/domain/native-mcp-connection-admission.d.ts +3 -0
- package/dist/domain/organization-integration-catalog.d.ts +15 -0
- package/dist/domain/personal-connection-delegations.d.ts +73 -12
- package/dist/domain/pr-review.d.ts +121 -6
- package/dist/domain/realtime-voice-billing.d.ts +103 -0
- package/dist/domain/resources.d.ts +17 -1
- package/dist/domain/scheduled-task-access.d.ts +265 -0
- package/dist/domain/scheduled-task-account-audit.d.ts +27 -0
- package/dist/domain/scheduled-task-audience.d.ts +70 -0
- package/dist/domain/scheduled-tasks.d.ts +61 -18
- package/dist/domain/session-connection-accounts.d.ts +53 -0
- package/dist/domain/session-file-access.d.ts +4 -0
- package/dist/domain/session-native-connection-replacement.d.ts +14 -0
- package/dist/domain/session-start-timing.d.ts +7 -0
- package/dist/domain/session-tool-policy.d.ts +102 -4
- package/dist/domain/sessions.d.ts +179 -15
- package/dist/domain/site-audience.d.ts +52 -0
- package/dist/domain/skills.d.ts +29 -1
- package/dist/domain/slack-bot.d.ts +46 -1
- package/dist/domain/slack-publication-secret-safety.d.ts +1 -1
- package/dist/domain/vaults/index.d.ts +7 -0
- package/dist/domain/vaults/mapping.d.ts +25 -0
- package/dist/domain/vaults/provider-registry.d.ts +72 -0
- package/dist/domain/vaults/provider-sync.d.ts +176 -0
- package/dist/domain/vaults/provider-writes.d.ts +57 -0
- package/dist/domain/vaults/secret-resolver.d.ts +34 -0
- package/dist/domain/vaults/types.d.ts +24 -0
- package/dist/domain/vaults/vault-service.d.ts +35 -0
- package/dist/domain/voice-input-billing.d.ts +77 -0
- package/dist/domain/web-search-billing.d.ts +51 -0
- package/dist/domain/workspace-credits.d.ts +7 -0
- package/dist/editable-artifact-live/application.d.ts +2 -1
- package/dist/editable-artifact-live/server.d.ts +5 -1
- package/dist/editable-artifact-live/ticket.d.ts +2 -1
- package/dist/editable-artifact-live/types.d.ts +9 -0
- package/dist/editable-artifact-live.js +2 -2
- package/dist/editable-artifacts.js +10 -2
- package/dist/goal-admission.d.ts +627 -0
- package/dist/host-session-usage-limit.d.ts +15 -0
- package/dist/index.d.ts +43 -8
- package/dist/index.js +22682 -11743
- package/dist/index.js.map +1 -1
- package/dist/managed-session.d.ts +110 -7
- package/dist/model-call.d.ts +58 -0
- package/dist/model-catalog.d.ts +29 -3
- package/dist/model-provider-credentials.d.ts +43 -0
- package/dist/product-usage-metrics.d.ts +30 -0
- package/dist/rigs/index.d.ts +1 -13
- package/dist/sandbox/fleet.d.ts +58 -4
- package/dist/sandbox/routing.d.ts +42 -2
- package/dist/sandbox/runtime-settings.d.ts +27 -17
- package/dist/session-authorization.d.ts +10 -0
- package/dist/session-usage-limit-metrics.d.ts +60 -0
- package/dist/session-usage-limits.d.ts +89 -0
- package/dist/site-agent-clamp.d.ts +71 -0
- package/dist/site-session-origin.d.ts +39 -2
- package/dist/transcription.d.ts +120 -3
- package/dist/turn-surface.d.ts +20 -0
- package/dist/user-presence.d.ts +32 -0
- package/dist/workflow-wake-contract.d.ts +13 -1
- package/package.json +15 -22
- package/src/access/index.ts +961 -38
- package/src/access/service-initiator.ts +50 -0
- package/src/application/api-integration-servers.ts +9 -0
- package/src/application/archived-session-imports.ts +161 -0
- package/src/application/composer-submit.ts +3 -2
- package/src/application/connect-authority.ts +3 -3
- package/src/application/connect-operation.ts +37 -3
- package/src/application/external-continuation.ts +20 -3
- package/src/application/external-link-work-admission.ts +3 -0
- package/src/application/external-workspace-members.ts +51 -3
- package/src/application/modal-native-live-declaration-join.ts +196 -0
- package/src/application/modal-native-original-configuration.ts +261 -0
- package/src/application/modal-native-worker-host-transport.ts +263 -0
- package/src/application/new-session-drafts.ts +172 -55
- package/src/application/organization-privacy.ts +161 -0
- package/src/application/prepared-mcp-connection.ts +133 -0
- package/src/application/sandbox-recovery.ts +78 -0
- package/src/application/session-commands.ts +73 -1
- package/src/application/session-mcp-credential-rotation.ts +61 -18
- package/src/application/session-tenancy.ts +262 -44
- package/src/application/user-resource-grants.ts +1 -29
- package/src/billing/agent-run-admission.ts +117 -0
- package/src/billing/limits.ts +138 -14
- package/src/billing/model-call-admission.ts +118 -0
- package/src/billing/model-usage-settlement.ts +472 -0
- package/src/codex-model-availability.ts +264 -0
- package/src/default-session-model.ts +692 -0
- package/src/dependencies.ts +48 -6
- package/src/developer-setup-credential-ceiling.ts +60 -0
- package/src/domain/agent-config-resolution.ts +148 -0
- package/src/domain/automations.ts +76 -2
- package/src/domain/capabilities.ts +830 -181
- package/src/domain/connection-account-selection-error.ts +19 -0
- package/src/domain/connector-tool-permissions.ts +572 -0
- package/src/domain/direct-model-provider.ts +62 -0
- package/src/domain/editable-artifacts/agent-application.ts +44 -6
- package/src/domain/editable-artifacts/durable-export.ts +100 -5
- package/src/domain/editable-artifacts/in-memory.ts +6 -0
- package/src/domain/editable-artifacts/ports.ts +11 -0
- package/src/domain/editable-artifacts/service.ts +20 -0
- package/src/domain/editable-artifacts/types.ts +1 -1
- package/src/domain/encryption-key.ts +26 -0
- package/src/domain/file-owner.ts +16 -1
- package/src/domain/github-action-policies.ts +1 -1
- package/src/domain/github-skill-source.ts +3 -1
- package/src/domain/insights-timing.ts +95 -0
- package/src/domain/insights-usage.ts +67 -0
- package/src/domain/insights.ts +167 -43
- package/src/domain/knowledge-files.ts +10 -3
- package/src/domain/knowledge-messages.ts +1 -0
- package/src/domain/knowledge-preparation.test.ts +276 -0
- package/src/domain/knowledge-preparation.ts +147 -0
- package/src/domain/knowledge-search.test.ts +617 -5
- package/src/domain/knowledge-search.ts +240 -23
- package/src/domain/mcp-account-bindings.ts +169 -0
- package/src/domain/mcp-account-routes.ts +152 -0
- package/src/domain/native-mcp-connection-admission.ts +14 -0
- package/src/domain/organization-integration-catalog.ts +88 -0
- package/src/domain/personal-connection-delegations.ts +399 -257
- package/src/domain/pr-review.ts +24 -8
- package/src/domain/realtime-voice-billing.ts +425 -0
- package/src/domain/resources.ts +50 -4
- package/src/domain/scheduled-task-access.ts +1089 -0
- package/src/domain/scheduled-task-account-audit.ts +90 -0
- package/src/domain/scheduled-task-audience.ts +249 -0
- package/src/domain/scheduled-tasks.ts +1313 -374
- package/src/domain/session-connection-accounts.ts +239 -0
- package/src/domain/session-file-access.ts +47 -0
- package/src/domain/session-native-connection-replacement.ts +64 -0
- package/src/domain/session-start-timing.ts +60 -0
- package/src/domain/session-tool-policy.ts +489 -14
- package/src/domain/sessions.ts +2254 -717
- package/src/domain/site-audience.ts +130 -0
- package/src/domain/skills.ts +9 -0
- package/src/domain/slack-bot.ts +141 -4
- package/src/domain/slack-publication-secret-safety.ts +1 -1
- package/src/domain/vaults/index.ts +19 -0
- package/src/domain/vaults/mapping.ts +190 -0
- package/src/domain/vaults/provider-registry.ts +201 -0
- package/src/domain/vaults/provider-sync.ts +531 -0
- package/src/domain/vaults/provider-writes.ts +288 -0
- package/src/domain/vaults/secret-resolver.ts +464 -0
- package/src/domain/vaults/types.ts +26 -0
- package/src/domain/vaults/vault-service.ts +1316 -0
- package/src/domain/voice-input-billing.ts +330 -0
- package/src/domain/web-search-billing.ts +169 -0
- package/src/domain/workspace-credits.ts +13 -0
- package/src/editable-artifact-live/application.ts +8 -1
- package/src/editable-artifact-live/server.ts +154 -6
- package/src/editable-artifact-live/ticket.ts +86 -1
- package/src/editable-artifact-live/types.ts +10 -0
- package/src/goal-admission.ts +220 -0
- package/src/host-session-usage-limit.ts +25 -0
- package/src/index.ts +75 -11
- package/src/managed-session.ts +137 -6
- package/src/model-call.ts +79 -0
- package/src/model-catalog.ts +345 -91
- package/src/model-provider-credentials.ts +394 -0
- package/src/product-usage-metrics.ts +101 -0
- package/src/rigs/index.ts +23 -111
- package/src/sandbox/fleet.ts +253 -28
- package/src/sandbox/routing.ts +204 -43
- package/src/sandbox/runtime-settings.ts +159 -85
- package/src/session-authorization.ts +172 -23
- package/src/session-usage-limit-metrics.ts +95 -0
- package/src/session-usage-limits.ts +415 -0
- package/src/site-agent-clamp.ts +226 -0
- package/src/site-session-origin.ts +84 -5
- package/src/transcription.ts +123 -4
- package/src/turn-surface.ts +47 -0
- package/src/user-presence.ts +134 -0
- package/src/workflow-wake-contract.ts +14 -1
- package/dist/application/host-mcp-owner.d.ts +0 -6
- package/dist/application/host-mcp-resolvers.d.ts +0 -13
- package/dist/chunk-5WZYFL45.js +0 -266
- package/dist/chunk-5WZYFL45.js.map +0 -1
- package/dist/chunk-H7X52RI2.js.map +0 -1
- package/dist/chunk-OF65T3PM.js.map +0 -1
- package/dist/chunk-VCZFFEPB.js.map +0 -1
- package/dist/chunk-ZYCNLYGH.js.map +0 -1
- package/dist/domain/connection-authority.d.ts +0 -97
- package/dist/domain/connection-authority.js +0 -169
- package/dist/domain/connection-authority.js.map +0 -1
- package/dist/domain/environments.d.ts +0 -33
- package/dist/domain/host-mcp-authority-source-admission.d.ts +0 -10
- package/dist/domain/host-mcp-task-admission.d.ts +0 -18
- package/dist/domain/packs.d.ts +0 -59
- package/dist/domain/product-integration-pack.d.ts +0 -44
- package/dist/domain/product-integration-skill.gen.d.ts +0 -5
- package/dist/remote-mcp-credentials.d.ts +0 -23
- package/dist/remote-mcp-credentials.js +0 -11
- package/dist/remote-mcp-credentials.js.map +0 -1
- package/src/application/host-mcp-owner.ts +0 -41
- package/src/application/host-mcp-resolvers.ts +0 -84
- package/src/domain/connection-authority.ts +0 -329
- package/src/domain/environments.ts +0 -120
- package/src/domain/host-mcp-authority-source-admission.ts +0 -25
- package/src/domain/host-mcp-task-admission.ts +0 -121
- package/src/domain/packs.ts +0 -699
- package/src/domain/product-integration-pack.ts +0 -42
- package/src/domain/product-integration-skill.gen.ts +0 -52
- package/src/remote-mcp-credentials.ts +0 -361
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { CODEX_CLIENT_VERSION, fetchCodexModels } from "@opengeni/codex";
|
|
2
|
+
import { configuredModels, withCodexCatalogProvider, type Settings } from "@opengeni/config";
|
|
3
|
+
import {
|
|
4
|
+
buildSubscriptionCoreCodexConnectionTokenResolver,
|
|
5
|
+
buildSubscriptionCoreCodexOperationFetch,
|
|
6
|
+
listSubscriptionCoreCodexServingConnections,
|
|
7
|
+
readCodexCutoverDisposition,
|
|
8
|
+
subscriptionCoreCodexConnectionAllowsModel,
|
|
9
|
+
recordSubscriptionCoreCodexModelCatalog,
|
|
10
|
+
SUBSCRIPTION_MODEL_CATALOG_TTL_MS,
|
|
11
|
+
type CodexCredentialTokenSnapshot,
|
|
12
|
+
type Database,
|
|
13
|
+
type SubscriptionCoreCodexServingConnection,
|
|
14
|
+
} from "@opengeni/db";
|
|
15
|
+
import type { ModelAvailabilityObservation } from "./model-catalog";
|
|
16
|
+
|
|
17
|
+
const CATALOG_CACHE_MS = SUBSCRIPTION_MODEL_CATALOG_TTL_MS;
|
|
18
|
+
const CATALOG_ERROR_CACHE_MS = 5_000;
|
|
19
|
+
type CatalogCacheEntry = {
|
|
20
|
+
expiresAt: number;
|
|
21
|
+
result: Promise<{ ok: boolean; slugs: string[]; checkedAt: string }>;
|
|
22
|
+
};
|
|
23
|
+
const catalogs = new Map<string, CatalogCacheEntry>();
|
|
24
|
+
|
|
25
|
+
/** The workspace, organization and acting subject of a Codex catalog read. */
|
|
26
|
+
export type WorkspaceCodexCatalogContext = {
|
|
27
|
+
accountId: string;
|
|
28
|
+
workspaceId: string;
|
|
29
|
+
/**
|
|
30
|
+
* The person whose new work the catalog describes: the authenticated
|
|
31
|
+
* caller, or a scheduled task's execution owner. Their own personal
|
|
32
|
+
* connection counts only in their own Personal workspace; null or a
|
|
33
|
+
* non-human subject sees shared capacity only.
|
|
34
|
+
*/
|
|
35
|
+
subjectId: string | null;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type WorkspaceCodexCatalogReadiness = {
|
|
39
|
+
/** Codex models are ready in this workspace (the catalog's connection readiness). */
|
|
40
|
+
active: boolean;
|
|
41
|
+
/** Live per-model availability, keyed by model definition version. */
|
|
42
|
+
observations: Record<string, ModelAvailabilityObservation>;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
type CatalogDependencies = {
|
|
46
|
+
recordModels: typeof recordSubscriptionCoreCodexModelCatalog;
|
|
47
|
+
disposition: typeof readCodexCutoverDisposition;
|
|
48
|
+
listServing: typeof listSubscriptionCoreCodexServingConnections;
|
|
49
|
+
fetchModels: typeof fetchCodexModels;
|
|
50
|
+
getCoreToken: (
|
|
51
|
+
db: Database,
|
|
52
|
+
settings: Settings,
|
|
53
|
+
context: WorkspaceCodexCatalogContext,
|
|
54
|
+
connectionId: string,
|
|
55
|
+
) => Promise<CodexCredentialTokenSnapshot>;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const CATALOG_SERVICE_SUBJECT = "service:subscription-core";
|
|
59
|
+
|
|
60
|
+
const defaultCatalogDependencies = (): CatalogDependencies => ({
|
|
61
|
+
recordModels: recordSubscriptionCoreCodexModelCatalog,
|
|
62
|
+
disposition: readCodexCutoverDisposition,
|
|
63
|
+
listServing: listSubscriptionCoreCodexServingConnections,
|
|
64
|
+
fetchModels: fetchCodexModels,
|
|
65
|
+
// A connection-level read (no operation lease), like live usage: the 0671
|
|
66
|
+
// seam serves only shared organization- or workspace-scoped connections in
|
|
67
|
+
// this workspace's scope, and refreshes under the per-connection key.
|
|
68
|
+
getCoreToken: (targetDb, targetSettings, context, connectionId) =>
|
|
69
|
+
buildSubscriptionCoreCodexConnectionTokenResolver(
|
|
70
|
+
targetDb,
|
|
71
|
+
targetSettings,
|
|
72
|
+
{
|
|
73
|
+
kind: "workspace",
|
|
74
|
+
accountId: context.accountId,
|
|
75
|
+
workspaceId: context.workspaceId,
|
|
76
|
+
subjectId: context.subjectId ?? CATALOG_SERVICE_SUBJECT,
|
|
77
|
+
},
|
|
78
|
+
connectionId,
|
|
79
|
+
null,
|
|
80
|
+
).getToken(),
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
function codexCatalogModels(settings: Settings) {
|
|
84
|
+
return configuredModels(withCodexCatalogProvider(settings)).filter(
|
|
85
|
+
(model) =>
|
|
86
|
+
model.credentialSource.kind === "connected_subscription" &&
|
|
87
|
+
model.credentialSource.provider === "codex",
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** One shared core connection's live model list (cached per refresh generation). */
|
|
92
|
+
async function loadCoreConnectionCatalog(
|
|
93
|
+
db: Database,
|
|
94
|
+
settings: Settings,
|
|
95
|
+
context: WorkspaceCodexCatalogContext,
|
|
96
|
+
connection: SubscriptionCoreCodexServingConnection,
|
|
97
|
+
deps: CatalogDependencies,
|
|
98
|
+
): Promise<{ ok: boolean; slugs: string[]; checkedAt: string }> {
|
|
99
|
+
try {
|
|
100
|
+
// The token read rechecks the enabled cutover and the workspace scope
|
|
101
|
+
// before the cache is consulted.
|
|
102
|
+
const token = await deps.getCoreToken(db, settings, context, connection.connectionId);
|
|
103
|
+
const key = `core:${context.workspaceId}:${connection.connectionId}:${token.credentialVersion}`;
|
|
104
|
+
const cached = catalogs.get(key);
|
|
105
|
+
if (cached && cached.expiresAt > Date.now()) return await cached.result;
|
|
106
|
+
for (const [id, entry] of catalogs) {
|
|
107
|
+
if (entry.expiresAt <= Date.now()) catalogs.delete(id);
|
|
108
|
+
}
|
|
109
|
+
if (catalogs.size >= 1_024) catalogs.delete(catalogs.keys().next().value!);
|
|
110
|
+
const entry: CatalogCacheEntry = {
|
|
111
|
+
expiresAt: Date.now() + CATALOG_CACHE_MS,
|
|
112
|
+
result: deps
|
|
113
|
+
.fetchModels(
|
|
114
|
+
{
|
|
115
|
+
accessToken: token.accessToken,
|
|
116
|
+
chatgptAccountId: token.chatgptAccountId,
|
|
117
|
+
isFedramp: token.isFedramp,
|
|
118
|
+
clientVersion: CODEX_CLIENT_VERSION,
|
|
119
|
+
},
|
|
120
|
+
buildSubscriptionCoreCodexOperationFetch(
|
|
121
|
+
db,
|
|
122
|
+
{
|
|
123
|
+
kind: "workspace",
|
|
124
|
+
accountId: context.accountId,
|
|
125
|
+
workspaceId: context.workspaceId,
|
|
126
|
+
subjectId: context.subjectId ?? CATALOG_SERVICE_SUBJECT,
|
|
127
|
+
},
|
|
128
|
+
null,
|
|
129
|
+
connection.connectionId,
|
|
130
|
+
),
|
|
131
|
+
)
|
|
132
|
+
.catch(() => ({ ok: false, slugs: [] as string[] }))
|
|
133
|
+
.then(async (result) => {
|
|
134
|
+
entry.expiresAt = Date.now() + (result.ok ? CATALOG_CACHE_MS : CATALOG_ERROR_CACHE_MS);
|
|
135
|
+
const observedAt = Date.now();
|
|
136
|
+
if (result.ok && token.credentialVersion !== null) {
|
|
137
|
+
await deps.recordModels(
|
|
138
|
+
db,
|
|
139
|
+
{
|
|
140
|
+
kind: "workspace",
|
|
141
|
+
...context,
|
|
142
|
+
subjectId: context.subjectId ?? CATALOG_SERVICE_SUBJECT,
|
|
143
|
+
},
|
|
144
|
+
connection.connectionId,
|
|
145
|
+
{ slugs: result.slugs, refreshGeneration: token.credentialVersion, observedAt },
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
ok: result.ok,
|
|
150
|
+
slugs: result.slugs,
|
|
151
|
+
checkedAt: new Date(observedAt).toISOString(),
|
|
152
|
+
};
|
|
153
|
+
}),
|
|
154
|
+
};
|
|
155
|
+
catalogs.set(key, entry);
|
|
156
|
+
return await entry.result;
|
|
157
|
+
} catch {
|
|
158
|
+
return { ok: false, slugs: [], checkedAt: new Date().toISOString() };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Placement consumes the same per-account catalog facts as the picker, never
|
|
164
|
+
* the union of another account's entitlements. Failed reads remain unknown.
|
|
165
|
+
* Personal credentials require an accepted-turn lease and are not probed by
|
|
166
|
+
* this workspace reader; their proven refusals remain model cooldowns.
|
|
167
|
+
*/
|
|
168
|
+
export async function refreshCoreCodexModelEntitlements(
|
|
169
|
+
db: Database,
|
|
170
|
+
settings: Settings,
|
|
171
|
+
context: WorkspaceCodexCatalogContext,
|
|
172
|
+
deps: CatalogDependencies = defaultCatalogDependencies(),
|
|
173
|
+
): Promise<void> {
|
|
174
|
+
if ((await deps.disposition(db, context.accountId, context.workspaceId)) !== "core") return;
|
|
175
|
+
const connections = await deps.listServing(db, context);
|
|
176
|
+
await Promise.all(
|
|
177
|
+
connections
|
|
178
|
+
.filter((connection) => connection.ownership === "shared")
|
|
179
|
+
.map((connection) => loadCoreConnectionCatalog(db, settings, context, connection, deps)),
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Codex readiness and live model availability for a workspace catalog,
|
|
185
|
+
* default-model or picker read, by the organization's Codex cutover row:
|
|
186
|
+
*
|
|
187
|
+
* - a missing or disabled row (maintenance): Codex is not ready and no legacy Codex
|
|
188
|
+
* table is read;
|
|
189
|
+
* - an enabled row (`core`): the core connections that can serve new work of
|
|
190
|
+
* `context.subjectId` here. A shared connection's live model list is read
|
|
191
|
+
* through the connection-level core seam. A personal connection's list
|
|
192
|
+
* cannot be read outside an exact accepted turn, so a model it permits and
|
|
193
|
+
* has not been refused for (no live model cooldown) is reported without an
|
|
194
|
+
* observation (selectable, status unknown); placement still decides.
|
|
195
|
+
*/
|
|
196
|
+
export async function loadWorkspaceCodexCatalogReadiness(
|
|
197
|
+
db: Database,
|
|
198
|
+
settings: Settings,
|
|
199
|
+
context: WorkspaceCodexCatalogContext,
|
|
200
|
+
options: {
|
|
201
|
+
observeAvailability?: boolean;
|
|
202
|
+
/** Deployment-level readiness settings, when different from the model catalog. */
|
|
203
|
+
activeSettings?: Pick<Settings, "codexSubscriptionEnabled">;
|
|
204
|
+
} = {},
|
|
205
|
+
deps: CatalogDependencies = defaultCatalogDependencies(),
|
|
206
|
+
): Promise<WorkspaceCodexCatalogReadiness> {
|
|
207
|
+
const activeSettings = options.activeSettings ?? settings;
|
|
208
|
+
const observe = options.observeAvailability !== false;
|
|
209
|
+
// Codex disabled for the deployment: never ready, nothing read.
|
|
210
|
+
if (!activeSettings.codexSubscriptionEnabled) return { active: false, observations: {} };
|
|
211
|
+
const disposition = await deps.disposition(db, context.accountId, context.workspaceId);
|
|
212
|
+
if (disposition === "maintenance") return { active: false, observations: {} };
|
|
213
|
+
const serving = await deps.listServing(db, context);
|
|
214
|
+
if (!observe || !settings.codexSubscriptionEnabled || serving.length === 0) {
|
|
215
|
+
return { active: serving.length > 0, observations: {} };
|
|
216
|
+
}
|
|
217
|
+
const shared = serving.filter((connection) => connection.ownership === "shared");
|
|
218
|
+
const personal = serving.filter((connection) => connection.ownership === "personal");
|
|
219
|
+
const live = await Promise.all(
|
|
220
|
+
shared.map(async (connection) => ({
|
|
221
|
+
connection,
|
|
222
|
+
...(await loadCoreConnectionCatalog(db, settings, context, connection, deps)),
|
|
223
|
+
})),
|
|
224
|
+
);
|
|
225
|
+
const observations: Record<string, ModelAvailabilityObservation> = {};
|
|
226
|
+
for (const model of codexCatalogModels(settings)) {
|
|
227
|
+
// Support and permission must hold on the SAME serving connection.
|
|
228
|
+
const permitted = live.filter(({ connection }) =>
|
|
229
|
+
subscriptionCoreCodexConnectionAllowsModel(connection, model.id),
|
|
230
|
+
);
|
|
231
|
+
const reachable = permitted.filter(({ ok }) => ok);
|
|
232
|
+
const supported = reachable.find(({ slugs }) => slugs.includes(model.upstreamModelId));
|
|
233
|
+
if (supported) {
|
|
234
|
+
observations[model.definitionVersion] = {
|
|
235
|
+
status: "available",
|
|
236
|
+
reason: null,
|
|
237
|
+
checkedAt: supported.checkedAt,
|
|
238
|
+
};
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
// The person's own connection may serve it: its list is unknown here.
|
|
242
|
+
if (
|
|
243
|
+
personal.some(
|
|
244
|
+
(connection) =>
|
|
245
|
+
subscriptionCoreCodexConnectionAllowsModel(connection, model.id) &&
|
|
246
|
+
!connection.cooledDownModelIds.includes(model.id),
|
|
247
|
+
)
|
|
248
|
+
) {
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
// A reachable Free account cannot establish that an unreachable Pro
|
|
252
|
+
// account lacks entitlement. Only definitive observations may deny it.
|
|
253
|
+
// Omit a negative observation when a permitted account is unknown. The
|
|
254
|
+
// shared catalog projects this as selectable/unknown, not unavailable;
|
|
255
|
+
// actual placement still rechecks scope, health and plan per account.
|
|
256
|
+
if (permitted.some(({ ok }) => !ok)) continue;
|
|
257
|
+
observations[model.definitionVersion] = {
|
|
258
|
+
status: "unavailable",
|
|
259
|
+
reason: "not_entitled",
|
|
260
|
+
checkedAt: permitted[0]?.checkedAt ?? new Date().toISOString(),
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return { active: true, observations };
|
|
264
|
+
}
|