@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
package/src/model-catalog.ts
CHANGED
|
@@ -1,19 +1,29 @@
|
|
|
1
1
|
import { modelAllowedByConnections, type ConnectionModelRestrictions } from "@opengeni/db";
|
|
2
2
|
import {
|
|
3
|
+
withDirectModelProviders,
|
|
3
4
|
applyModelCatalogDocument,
|
|
5
|
+
CLAUDE_CONNECTION_KINDS,
|
|
6
|
+
claudeProviderId,
|
|
7
|
+
withClaudeConnectionCatalog,
|
|
8
|
+
type ClaudeConnectionCatalog,
|
|
4
9
|
configuredGatewayWorkspaceProductModelIds,
|
|
5
10
|
configuredGatewayOrganizationProductModelIds,
|
|
6
11
|
configuredModels,
|
|
12
|
+
isModelAvailableForNewSelection,
|
|
7
13
|
configuredModelNotes,
|
|
8
14
|
configuredOpenRouterWorkspaceProductModelIds,
|
|
9
15
|
configuredOpenRouterOrganizationProductModelIds,
|
|
16
|
+
configuredOpperWorkspaceProductModelIds,
|
|
17
|
+
configuredOpperOrganizationProductModelIds,
|
|
10
18
|
configuredProviders,
|
|
11
19
|
validateModelCatalogSettings,
|
|
12
20
|
withCodexCatalogProvider,
|
|
13
21
|
withOrganizationGatewayCatalogProvider,
|
|
14
22
|
withOrganizationOpenRouterCatalogProvider,
|
|
23
|
+
withOrganizationOpperCatalogProvider,
|
|
15
24
|
withWorkspaceGatewayCatalogProvider,
|
|
16
25
|
withWorkspaceOpenRouterCatalogProvider,
|
|
26
|
+
withWorkspaceOpperCatalogProvider,
|
|
17
27
|
withXaiSubscriptionCatalogProvider,
|
|
18
28
|
WORKSPACE_GATEWAY_MODEL_ID_PREFIX,
|
|
19
29
|
WORKSPACE_OPENROUTER_MODEL_ID_PREFIX,
|
|
@@ -21,6 +31,10 @@ import {
|
|
|
21
31
|
ORGANIZATION_OPENROUTER_PROVIDER_ID,
|
|
22
32
|
ORGANIZATION_GATEWAY_MODEL_ID_PREFIX,
|
|
23
33
|
ORGANIZATION_OPENROUTER_MODEL_ID_PREFIX,
|
|
34
|
+
WORKSPACE_OPPER_MODEL_ID_PREFIX,
|
|
35
|
+
WORKSPACE_OPPER_PROVIDER_ID,
|
|
36
|
+
ORGANIZATION_OPPER_MODEL_ID_PREFIX,
|
|
37
|
+
ORGANIZATION_OPPER_PROVIDER_ID,
|
|
24
38
|
type ConfiguredModel,
|
|
25
39
|
type Settings,
|
|
26
40
|
} from "@opengeni/config";
|
|
@@ -31,17 +45,21 @@ import {
|
|
|
31
45
|
type WorkspaceModelPolicyContract,
|
|
32
46
|
} from "@opengeni/contracts";
|
|
33
47
|
import {
|
|
48
|
+
listConnectionsMetadata,
|
|
34
49
|
getDeploymentModelCatalog,
|
|
50
|
+
listWorkspaceProviderCustomModelsByKind,
|
|
51
|
+
getWorkspaceProviderCustomModelForExecution,
|
|
52
|
+
lockActiveWorkspaceProviderCustomModelForAdmission,
|
|
35
53
|
getWorkspaceGatewayCustomModelForExecution,
|
|
36
54
|
getWorkspaceOpenRouterCustomModelForExecution,
|
|
37
55
|
getOrganizationModelProviderCustomModelForExecution,
|
|
38
|
-
|
|
39
|
-
listWorkspaceOpenRouterCustomModels,
|
|
40
|
-
listOrganizationModelProviderCustomModelsForWorkspace,
|
|
56
|
+
getOrganizationModelProviderCatalogForWorkspace,
|
|
41
57
|
lockActiveOrganizationModelProviderCustomModelForAdmission,
|
|
42
|
-
lockActiveWorkspaceGatewayCustomModelForAdmission,
|
|
43
|
-
lockActiveWorkspaceOpenRouterCustomModelForAdmission,
|
|
44
58
|
type Database,
|
|
59
|
+
type OrganizationClaudeModelAdmissionAuthority,
|
|
60
|
+
type WorkspaceCustomModelProviderKind,
|
|
61
|
+
type WorkspaceGatewayCustomModel,
|
|
62
|
+
type WorkspaceOpenRouterCustomModel,
|
|
45
63
|
} from "@opengeni/db";
|
|
46
64
|
|
|
47
65
|
export type ResolvedCatalogSettings = {
|
|
@@ -70,9 +88,16 @@ export function isWorkspaceOpenRouterCustomModelId(settings: Settings, modelId:
|
|
|
70
88
|
);
|
|
71
89
|
}
|
|
72
90
|
|
|
91
|
+
export function isWorkspaceOpperCustomModelId(settings: Settings, modelId: string): boolean {
|
|
92
|
+
return (
|
|
93
|
+
modelId.startsWith(WORKSPACE_OPPER_MODEL_ID_PREFIX) &&
|
|
94
|
+
!configuredOpperWorkspaceProductModelIds(settings).includes(modelId)
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
73
98
|
export type WorkspaceCustomModelReference = {
|
|
74
99
|
scope: "workspace" | "organization";
|
|
75
|
-
providerKind: "vercel_gateway" | "openrouter";
|
|
100
|
+
providerKind: "vercel_gateway" | "openrouter" | "anthropic" | "claude_subscription" | "opper";
|
|
76
101
|
upstreamModelId: string;
|
|
77
102
|
};
|
|
78
103
|
|
|
@@ -80,6 +105,16 @@ export function workspaceCustomModelReference(
|
|
|
80
105
|
settings: Settings,
|
|
81
106
|
modelId: string,
|
|
82
107
|
): WorkspaceCustomModelReference | null {
|
|
108
|
+
for (const scope of ["workspace", "organization"] as const)
|
|
109
|
+
for (const kind of CLAUDE_CONNECTION_KINDS) {
|
|
110
|
+
const prefix = claudeProviderId(kind, scope) + "/";
|
|
111
|
+
if (modelId.startsWith(prefix))
|
|
112
|
+
return {
|
|
113
|
+
scope,
|
|
114
|
+
providerKind: kind,
|
|
115
|
+
upstreamModelId: modelId.slice(prefix.length),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
83
118
|
if (isWorkspaceGatewayCustomModelId(settings, modelId)) {
|
|
84
119
|
return {
|
|
85
120
|
scope: "workspace",
|
|
@@ -94,6 +129,23 @@ export function workspaceCustomModelReference(
|
|
|
94
129
|
upstreamModelId: modelId.slice(WORKSPACE_OPENROUTER_MODEL_ID_PREFIX.length),
|
|
95
130
|
};
|
|
96
131
|
}
|
|
132
|
+
if (isWorkspaceOpperCustomModelId(settings, modelId)) {
|
|
133
|
+
return {
|
|
134
|
+
scope: "workspace",
|
|
135
|
+
providerKind: "opper",
|
|
136
|
+
upstreamModelId: modelId.slice(WORKSPACE_OPPER_MODEL_ID_PREFIX.length),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
if (
|
|
140
|
+
modelId.startsWith(ORGANIZATION_OPPER_MODEL_ID_PREFIX) &&
|
|
141
|
+
!configuredOpperOrganizationProductModelIds(settings).includes(modelId)
|
|
142
|
+
) {
|
|
143
|
+
return {
|
|
144
|
+
scope: "organization",
|
|
145
|
+
providerKind: "opper",
|
|
146
|
+
upstreamModelId: modelId.slice(ORGANIZATION_OPPER_MODEL_ID_PREFIX.length),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
97
149
|
if (
|
|
98
150
|
modelId.startsWith(ORGANIZATION_GATEWAY_MODEL_ID_PREFIX) &&
|
|
99
151
|
!configuredGatewayOrganizationProductModelIds(settings).includes(modelId)
|
|
@@ -127,6 +179,12 @@ export async function lockActiveCustomModelForAdmission(
|
|
|
127
179
|
accountId: string;
|
|
128
180
|
workspaceId: string;
|
|
129
181
|
reference: WorkspaceCustomModelReference;
|
|
182
|
+
/**
|
|
183
|
+
* The accepted Claude authority this admission re-reads. Every caller
|
|
184
|
+
* states it: an organization Claude model is never admitted without it,
|
|
185
|
+
* so an omitted value would refuse that model silently.
|
|
186
|
+
*/
|
|
187
|
+
claudeAuthority: OrganizationClaudeModelAdmissionAuthority | null;
|
|
130
188
|
},
|
|
131
189
|
): Promise<boolean> {
|
|
132
190
|
if (input.reference.scope === "organization") {
|
|
@@ -135,22 +193,18 @@ export async function lockActiveCustomModelForAdmission(
|
|
|
135
193
|
accountId: input.accountId,
|
|
136
194
|
workspaceId: input.workspaceId,
|
|
137
195
|
providerKind: input.reference.providerKind,
|
|
196
|
+
...(input.claudeAuthority ? { claudeAuthority: input.claudeAuthority } : {}),
|
|
138
197
|
upstreamModelId: input.reference.upstreamModelId,
|
|
139
198
|
}),
|
|
140
199
|
);
|
|
141
200
|
}
|
|
142
201
|
return Boolean(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
: await lockActiveWorkspaceGatewayCustomModelForAdmission(db, {
|
|
150
|
-
accountId: input.accountId,
|
|
151
|
-
workspaceId: input.workspaceId,
|
|
152
|
-
upstreamModelId: input.reference.upstreamModelId,
|
|
153
|
-
}),
|
|
202
|
+
await lockActiveWorkspaceProviderCustomModelForAdmission(db, {
|
|
203
|
+
accountId: input.accountId,
|
|
204
|
+
workspaceId: input.workspaceId,
|
|
205
|
+
providerKind: input.reference.providerKind,
|
|
206
|
+
upstreamModelId: input.reference.upstreamModelId,
|
|
207
|
+
}),
|
|
154
208
|
);
|
|
155
209
|
}
|
|
156
210
|
|
|
@@ -233,25 +287,48 @@ export async function resolveWorkspaceCatalogSettings(
|
|
|
233
287
|
? [productModelId.slice(ORGANIZATION_OPENROUTER_MODEL_ID_PREFIX.length)]
|
|
234
288
|
: [],
|
|
235
289
|
);
|
|
290
|
+
const retainedOpperUpstreamModelIds = retainedProductModelIds.flatMap((productModelId) =>
|
|
291
|
+
productModelId?.startsWith(WORKSPACE_OPPER_MODEL_ID_PREFIX)
|
|
292
|
+
? [productModelId.slice(WORKSPACE_OPPER_MODEL_ID_PREFIX.length)]
|
|
293
|
+
: [],
|
|
294
|
+
);
|
|
295
|
+
const retainedOrganizationOpperUpstreamModelIds = retainedProductModelIds.flatMap(
|
|
296
|
+
(productModelId) =>
|
|
297
|
+
productModelId?.startsWith(ORGANIZATION_OPPER_MODEL_ID_PREFIX)
|
|
298
|
+
? [productModelId.slice(ORGANIZATION_OPPER_MODEL_ID_PREFIX.length)]
|
|
299
|
+
: [],
|
|
300
|
+
);
|
|
301
|
+
// One scoped read per catalog family instead of one scoped transaction per
|
|
302
|
+
// provider kind. The batched readers keep each provider's filters, bound and
|
|
303
|
+
// overflow error. The Claude subscription flag is env-only (the catalog
|
|
304
|
+
// document never changes it), so it decides the requested kinds up front.
|
|
305
|
+
const workspaceCustomModelKinds: WorkspaceCustomModelProviderKind[] = [
|
|
306
|
+
"vercel_gateway",
|
|
307
|
+
"openrouter",
|
|
308
|
+
"opper",
|
|
309
|
+
...(supportsOrganizationProviderReads
|
|
310
|
+
? CLAUDE_CONNECTION_KINDS.filter(
|
|
311
|
+
(kind) => kind !== "claude_subscription" || envSettings.claudeSubscriptionEnabled,
|
|
312
|
+
)
|
|
313
|
+
: []),
|
|
314
|
+
];
|
|
236
315
|
const [
|
|
237
316
|
resolved,
|
|
238
|
-
|
|
239
|
-
activeOpenRouterCustomModels,
|
|
317
|
+
workspaceCustomModels,
|
|
240
318
|
retainedGatewayCustomModels,
|
|
241
319
|
retainedOpenRouterCustomModels,
|
|
242
|
-
|
|
243
|
-
organizationOpenRouterCustomModels,
|
|
320
|
+
organizationProviders,
|
|
244
321
|
retainedOrganizationGatewayCustomModels,
|
|
245
322
|
retainedOrganizationOpenRouterCustomModels,
|
|
323
|
+
directConnections,
|
|
324
|
+
retainedOpperCustomModels,
|
|
325
|
+
retainedOrganizationOpperCustomModels,
|
|
246
326
|
] = await Promise.all([
|
|
247
327
|
resolveCatalogSettings(db, envSettings),
|
|
248
|
-
|
|
249
|
-
accountId: input.accountId,
|
|
250
|
-
workspaceId: input.workspaceId,
|
|
251
|
-
}),
|
|
252
|
-
listWorkspaceOpenRouterCustomModels(db, {
|
|
328
|
+
listWorkspaceProviderCustomModelsByKind(db, {
|
|
253
329
|
accountId: input.accountId,
|
|
254
330
|
workspaceId: input.workspaceId,
|
|
331
|
+
providerKinds: workspaceCustomModelKinds,
|
|
255
332
|
}),
|
|
256
333
|
Promise.all(
|
|
257
334
|
[...new Set(retainedGatewayUpstreamModelIds)].map(
|
|
@@ -274,19 +351,12 @@ export async function resolveWorkspaceCatalogSettings(
|
|
|
274
351
|
),
|
|
275
352
|
),
|
|
276
353
|
supportsOrganizationProviderReads
|
|
277
|
-
?
|
|
354
|
+
? getOrganizationModelProviderCatalogForWorkspace(db, {
|
|
278
355
|
accountId: input.accountId,
|
|
279
356
|
workspaceId: input.workspaceId,
|
|
280
|
-
|
|
357
|
+
providerKinds: ["vercel_gateway", "openrouter", "opper", ...CLAUDE_CONNECTION_KINDS],
|
|
281
358
|
})
|
|
282
|
-
:
|
|
283
|
-
supportsOrganizationProviderReads
|
|
284
|
-
? listOrganizationModelProviderCustomModelsForWorkspace(db, {
|
|
285
|
-
accountId: input.accountId,
|
|
286
|
-
workspaceId: input.workspaceId,
|
|
287
|
-
providerKind: "openrouter",
|
|
288
|
-
})
|
|
289
|
-
: Promise.resolve([]),
|
|
359
|
+
: null,
|
|
290
360
|
supportsOrganizationProviderReads
|
|
291
361
|
? Promise.all(
|
|
292
362
|
[...new Set(retainedOrganizationGatewayUpstreamModelIds)].map(
|
|
@@ -313,6 +383,33 @@ export async function resolveWorkspaceCatalogSettings(
|
|
|
313
383
|
),
|
|
314
384
|
)
|
|
315
385
|
: Promise.resolve([]),
|
|
386
|
+
supportsOrganizationProviderReads
|
|
387
|
+
? listConnectionsMetadata(db, input.workspaceId, null)
|
|
388
|
+
: Promise.resolve([]),
|
|
389
|
+
Promise.all(
|
|
390
|
+
[...new Set(retainedOpperUpstreamModelIds)].map(
|
|
391
|
+
async (upstreamModelId) =>
|
|
392
|
+
await getWorkspaceProviderCustomModelForExecution(db, {
|
|
393
|
+
accountId: input.accountId,
|
|
394
|
+
workspaceId: input.workspaceId,
|
|
395
|
+
providerKind: "opper",
|
|
396
|
+
upstreamModelId,
|
|
397
|
+
}),
|
|
398
|
+
),
|
|
399
|
+
),
|
|
400
|
+
supportsOrganizationProviderReads
|
|
401
|
+
? Promise.all(
|
|
402
|
+
[...new Set(retainedOrganizationOpperUpstreamModelIds)].map(
|
|
403
|
+
async (upstreamModelId) =>
|
|
404
|
+
await getOrganizationModelProviderCustomModelForExecution(db, {
|
|
405
|
+
accountId: input.accountId,
|
|
406
|
+
workspaceId: input.workspaceId,
|
|
407
|
+
providerKind: "opper",
|
|
408
|
+
upstreamModelId,
|
|
409
|
+
}),
|
|
410
|
+
),
|
|
411
|
+
)
|
|
412
|
+
: Promise.resolve([]),
|
|
316
413
|
]);
|
|
317
414
|
const includeRetainedModels = <T extends { upstreamModelId: string }>(
|
|
318
415
|
activeModels: readonly T[],
|
|
@@ -332,32 +429,91 @@ export async function resolveWorkspaceCatalogSettings(
|
|
|
332
429
|
return customModels;
|
|
333
430
|
};
|
|
334
431
|
const gatewayCustomModels = includeRetainedModels(
|
|
335
|
-
|
|
432
|
+
workspaceCustomModels.vercel_gateway as WorkspaceGatewayCustomModel[],
|
|
336
433
|
retainedGatewayCustomModels,
|
|
337
434
|
);
|
|
338
435
|
const openRouterCustomModels = includeRetainedModels(
|
|
339
|
-
|
|
436
|
+
workspaceCustomModels.openrouter as WorkspaceOpenRouterCustomModel[],
|
|
340
437
|
retainedOpenRouterCustomModels,
|
|
341
438
|
);
|
|
342
439
|
const organizationGatewayModels = includeRetainedModels(
|
|
343
|
-
|
|
440
|
+
organizationProviders?.vercel_gateway.models ?? [],
|
|
344
441
|
retainedOrganizationGatewayCustomModels,
|
|
345
442
|
);
|
|
346
443
|
const organizationOpenRouterModels = includeRetainedModels(
|
|
347
|
-
|
|
444
|
+
organizationProviders?.openrouter.models ?? [],
|
|
348
445
|
retainedOrganizationOpenRouterCustomModels,
|
|
349
446
|
);
|
|
447
|
+
const opperCustomModels = includeRetainedModels(
|
|
448
|
+
workspaceCustomModels.opper ?? [],
|
|
449
|
+
retainedOpperCustomModels,
|
|
450
|
+
);
|
|
451
|
+
const organizationOpperModels = includeRetainedModels(
|
|
452
|
+
organizationProviders?.opper.models ?? [],
|
|
453
|
+
retainedOrganizationOpperCustomModels,
|
|
454
|
+
);
|
|
455
|
+
const claudeConnections: ClaudeConnectionCatalog = {};
|
|
456
|
+
if (organizationProviders)
|
|
457
|
+
for (const kind of CLAUDE_CONNECTION_KINDS) {
|
|
458
|
+
const models = [...organizationProviders[kind].models];
|
|
459
|
+
const prefix = claudeProviderId(kind) + "/";
|
|
460
|
+
for (const productId of retainedProductModelIds)
|
|
461
|
+
if (productId?.startsWith(prefix)) {
|
|
462
|
+
const retained = await getOrganizationModelProviderCustomModelForExecution(db, {
|
|
463
|
+
accountId: input.accountId,
|
|
464
|
+
workspaceId: input.workspaceId,
|
|
465
|
+
providerKind: kind,
|
|
466
|
+
upstreamModelId: productId.slice(prefix.length),
|
|
467
|
+
});
|
|
468
|
+
if (retained && !models.some((model) => model.id === retained.id)) models.push(retained);
|
|
469
|
+
}
|
|
470
|
+
claudeConnections[kind] = { models };
|
|
471
|
+
}
|
|
472
|
+
const workspaceClaudeConnections: ClaudeConnectionCatalog = {};
|
|
473
|
+
if (supportsOrganizationProviderReads)
|
|
474
|
+
for (const kind of CLAUDE_CONNECTION_KINDS) {
|
|
475
|
+
if (kind === "claude_subscription" && !resolved.settings.claudeSubscriptionEnabled) continue;
|
|
476
|
+
const models = [...workspaceCustomModels[kind]];
|
|
477
|
+
const prefix = claudeProviderId(kind, "workspace") + "/";
|
|
478
|
+
for (const productId of retainedProductModelIds) {
|
|
479
|
+
if (!productId?.startsWith(prefix)) continue;
|
|
480
|
+
const retained = await getWorkspaceProviderCustomModelForExecution(db, {
|
|
481
|
+
accountId: input.accountId,
|
|
482
|
+
workspaceId: input.workspaceId,
|
|
483
|
+
providerKind: kind,
|
|
484
|
+
upstreamModelId: productId.slice(prefix.length),
|
|
485
|
+
});
|
|
486
|
+
if (retained && !models.some((model) => model.id === retained.id)) models.push(retained);
|
|
487
|
+
}
|
|
488
|
+
workspaceClaudeConnections[kind] = { models };
|
|
489
|
+
}
|
|
350
490
|
return {
|
|
351
491
|
...resolved,
|
|
352
|
-
settings:
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
492
|
+
settings: withDirectModelProviders(
|
|
493
|
+
withClaudeConnectionCatalog(
|
|
494
|
+
withClaudeConnectionCatalog(
|
|
495
|
+
withOrganizationOpperCatalogProvider(
|
|
496
|
+
withWorkspaceOpperCatalogProvider(
|
|
497
|
+
withOrganizationOpenRouterCatalogProvider(
|
|
498
|
+
withOrganizationGatewayCatalogProvider(
|
|
499
|
+
withWorkspaceOpenRouterCatalogProvider(
|
|
500
|
+
withWorkspaceGatewayCatalogProvider(resolved.settings, gatewayCustomModels),
|
|
501
|
+
openRouterCustomModels,
|
|
502
|
+
),
|
|
503
|
+
organizationGatewayModels,
|
|
504
|
+
),
|
|
505
|
+
organizationOpenRouterModels,
|
|
506
|
+
),
|
|
507
|
+
opperCustomModels,
|
|
508
|
+
),
|
|
509
|
+
organizationOpperModels,
|
|
510
|
+
),
|
|
511
|
+
claudeConnections,
|
|
357
512
|
),
|
|
358
|
-
|
|
513
|
+
workspaceClaudeConnections,
|
|
514
|
+
"workspace",
|
|
359
515
|
),
|
|
360
|
-
|
|
516
|
+
directConnections,
|
|
361
517
|
),
|
|
362
518
|
};
|
|
363
519
|
}
|
|
@@ -387,8 +543,12 @@ export type WorkspaceModelSelectionInput = {
|
|
|
387
543
|
xaiSubscriptionActive?: boolean;
|
|
388
544
|
workspaceGatewayConnectionActive?: boolean;
|
|
389
545
|
workspaceOpenRouterConnectionActive?: boolean;
|
|
546
|
+
workspaceOpperConnectionActive?: boolean;
|
|
547
|
+
claudeConnections?: ClaudeConnectionCatalog;
|
|
548
|
+
workspaceClaudeConnections?: ClaudeConnectionCatalog;
|
|
390
549
|
organizationGatewayConnectionActive?: boolean;
|
|
391
550
|
organizationOpenRouterConnectionActive?: boolean;
|
|
551
|
+
organizationOpperConnectionActive?: boolean;
|
|
392
552
|
workspaceGatewayCustomModels?: readonly {
|
|
393
553
|
upstreamModelId: string;
|
|
394
554
|
label?: string | null;
|
|
@@ -405,6 +565,14 @@ export type WorkspaceModelSelectionInput = {
|
|
|
405
565
|
upstreamModelId: string;
|
|
406
566
|
label?: string | null;
|
|
407
567
|
}[];
|
|
568
|
+
workspaceOpperCustomModels?: readonly {
|
|
569
|
+
upstreamModelId: string;
|
|
570
|
+
label?: string | null;
|
|
571
|
+
}[];
|
|
572
|
+
organizationOpperCustomModels?: readonly {
|
|
573
|
+
upstreamModelId: string;
|
|
574
|
+
label?: string | null;
|
|
575
|
+
}[];
|
|
408
576
|
credentialReadinessObservations?:
|
|
409
577
|
| Readonly<Record<string, ModelCredentialReadinessObservation>>
|
|
410
578
|
| undefined;
|
|
@@ -428,6 +596,23 @@ function modelDefinitionRunnable(model: ConfiguredModel): boolean {
|
|
|
428
596
|
);
|
|
429
597
|
}
|
|
430
598
|
|
|
599
|
+
/**
|
|
600
|
+
* Stable fresh-selection admission, independent of transient observations.
|
|
601
|
+
* Missing catalog membership is handled by the caller's lookup. Resolver-based
|
|
602
|
+
* deployment credentials (Azure AD/managed identity) are resolved at execution;
|
|
603
|
+
* absent, stale or failed observations cannot make their definition uncreatable.
|
|
604
|
+
*/
|
|
605
|
+
export function isWorkspaceModelAdmissible(selection: WorkspaceModelSelection): boolean {
|
|
606
|
+
if (!modelDefinitionRunnable(selection.model) || !selection.policyAllowed) return false;
|
|
607
|
+
const source = selection.model.credentialSource;
|
|
608
|
+
if (source.kind === "deployment") {
|
|
609
|
+
return source.mechanism !== "api_key" || selection.credentialReadiness.status === "ready";
|
|
610
|
+
}
|
|
611
|
+
// Connected subscriptions and workspace/organization connections have a
|
|
612
|
+
// durable active/reauth prerequisite, unlike deployment credential resolvers.
|
|
613
|
+
return selection.credentialReadiness.status === "ready";
|
|
614
|
+
}
|
|
615
|
+
|
|
431
616
|
function observedCredentialReadiness(input: {
|
|
432
617
|
observation: ModelCredentialReadinessObservation | undefined;
|
|
433
618
|
basis: "connection" | "resolver";
|
|
@@ -487,8 +672,12 @@ function credentialReadinessFor(input: {
|
|
|
487
672
|
xaiSubscriptionActive: boolean;
|
|
488
673
|
workspaceGatewayConnectionActive: boolean;
|
|
489
674
|
workspaceOpenRouterConnectionActive: boolean;
|
|
675
|
+
workspaceOpperConnectionActive: boolean;
|
|
676
|
+
claudeConnections?: ClaudeConnectionCatalog | undefined;
|
|
677
|
+
workspaceClaudeConnections?: ClaudeConnectionCatalog | undefined;
|
|
490
678
|
organizationGatewayConnectionActive: boolean;
|
|
491
679
|
organizationOpenRouterConnectionActive: boolean;
|
|
680
|
+
organizationOpperConnectionActive: boolean;
|
|
492
681
|
observation: ModelCredentialReadinessObservation | undefined;
|
|
493
682
|
nowMs: number;
|
|
494
683
|
maxAgeMs: number;
|
|
@@ -496,7 +685,14 @@ function credentialReadinessFor(input: {
|
|
|
496
685
|
const source = input.model.credentialSource;
|
|
497
686
|
if (source.kind === "connected_subscription") {
|
|
498
687
|
const active =
|
|
499
|
-
source.provider === "xai"
|
|
688
|
+
source.provider === "xai"
|
|
689
|
+
? input.xaiSubscriptionActive
|
|
690
|
+
: source.provider === "claude"
|
|
691
|
+
? (input.model.providerId === claudeProviderId("claude_subscription", "workspace")
|
|
692
|
+
? input.workspaceClaudeConnections
|
|
693
|
+
: input.claudeConnections
|
|
694
|
+
)?.claude_subscription?.active === true
|
|
695
|
+
: input.codexSubscriptionActive;
|
|
500
696
|
return active
|
|
501
697
|
? { status: "ready", reason: null, basis: "connection", checkedAt: null }
|
|
502
698
|
: {
|
|
@@ -507,10 +703,20 @@ function credentialReadinessFor(input: {
|
|
|
507
703
|
};
|
|
508
704
|
}
|
|
509
705
|
if (source.kind === "workspace_connection") {
|
|
706
|
+
const claudeKind = CLAUDE_CONNECTION_KINDS.find(
|
|
707
|
+
(kind) => claudeProviderId(kind, "workspace") === input.model.providerId,
|
|
708
|
+
);
|
|
510
709
|
const connectionActive =
|
|
511
|
-
input.
|
|
512
|
-
|
|
513
|
-
|
|
710
|
+
input.provider?.kind === "direct-openai-workspace" ||
|
|
711
|
+
input.provider?.kind === "direct-azure-workspace"
|
|
712
|
+
? true
|
|
713
|
+
: claudeKind
|
|
714
|
+
? input.workspaceClaudeConnections?.[claudeKind]?.active === true
|
|
715
|
+
: input.model.providerId === WORKSPACE_OPENROUTER_PROVIDER_ID
|
|
716
|
+
? input.workspaceOpenRouterConnectionActive
|
|
717
|
+
: input.model.providerId === WORKSPACE_OPPER_PROVIDER_ID
|
|
718
|
+
? input.workspaceOpperConnectionActive
|
|
719
|
+
: input.workspaceGatewayConnectionActive;
|
|
514
720
|
return connectionActive
|
|
515
721
|
? { status: "ready", reason: null, basis: "connection", checkedAt: null }
|
|
516
722
|
: {
|
|
@@ -521,10 +727,16 @@ function credentialReadinessFor(input: {
|
|
|
521
727
|
};
|
|
522
728
|
}
|
|
523
729
|
if (source.kind === "organization_connection") {
|
|
524
|
-
const
|
|
525
|
-
input.model.providerId
|
|
730
|
+
const claudeKind = CLAUDE_CONNECTION_KINDS.find(
|
|
731
|
+
(kind) => claudeProviderId(kind) === input.model.providerId,
|
|
732
|
+
);
|
|
733
|
+
const connectionActive = claudeKind
|
|
734
|
+
? input.claudeConnections?.[claudeKind]?.active === true
|
|
735
|
+
: input.model.providerId === ORGANIZATION_OPENROUTER_PROVIDER_ID
|
|
526
736
|
? input.organizationOpenRouterConnectionActive
|
|
527
|
-
: input.
|
|
737
|
+
: input.model.providerId === ORGANIZATION_OPPER_PROVIDER_ID
|
|
738
|
+
? input.organizationOpperConnectionActive
|
|
739
|
+
: input.organizationGatewayConnectionActive;
|
|
528
740
|
return connectionActive
|
|
529
741
|
? { status: "ready", reason: null, basis: "connection", checkedAt: null }
|
|
530
742
|
: {
|
|
@@ -610,6 +822,8 @@ function availabilityFor(input: {
|
|
|
610
822
|
model: ConfiguredModel;
|
|
611
823
|
credentialReadiness: ModelCredentialReadinessV1;
|
|
612
824
|
policyAllowed: boolean;
|
|
825
|
+
/** Blocked only because the workspace turned Opengeni credits off. */
|
|
826
|
+
creditsDisabled?: boolean;
|
|
613
827
|
observation?: ModelAvailabilityObservation | undefined;
|
|
614
828
|
nowMs: number;
|
|
615
829
|
maxAgeMs: number;
|
|
@@ -639,7 +853,7 @@ function availabilityFor(input: {
|
|
|
639
853
|
return {
|
|
640
854
|
status: "unavailable",
|
|
641
855
|
selectable: false,
|
|
642
|
-
reason: "policy_blocked",
|
|
856
|
+
reason: input.creditsDisabled ? "credits_disabled" : "policy_blocked",
|
|
643
857
|
checkedAt: null,
|
|
644
858
|
};
|
|
645
859
|
}
|
|
@@ -683,15 +897,31 @@ export function resolveWorkspaceModelSelection(
|
|
|
683
897
|
const xaiSettings = input.settings.supergrokSubscriptionEnabled
|
|
684
898
|
? withXaiSubscriptionCatalogProvider(codexSettings)
|
|
685
899
|
: codexSettings;
|
|
686
|
-
const catalogSettings =
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
900
|
+
const catalogSettings = withClaudeConnectionCatalog(
|
|
901
|
+
withClaudeConnectionCatalog(
|
|
902
|
+
withOrganizationOpperCatalogProvider(
|
|
903
|
+
withWorkspaceOpperCatalogProvider(
|
|
904
|
+
withOrganizationOpenRouterCatalogProvider(
|
|
905
|
+
withOrganizationGatewayCatalogProvider(
|
|
906
|
+
withWorkspaceOpenRouterCatalogProvider(
|
|
907
|
+
withWorkspaceGatewayCatalogProvider(
|
|
908
|
+
xaiSettings,
|
|
909
|
+
input.workspaceGatewayCustomModels ?? [],
|
|
910
|
+
),
|
|
911
|
+
input.workspaceOpenRouterCustomModels ?? [],
|
|
912
|
+
),
|
|
913
|
+
input.organizationGatewayCustomModels ?? [],
|
|
914
|
+
),
|
|
915
|
+
input.organizationOpenRouterCustomModels ?? [],
|
|
916
|
+
),
|
|
917
|
+
input.workspaceOpperCustomModels ?? [],
|
|
918
|
+
),
|
|
919
|
+
input.organizationOpperCustomModels ?? [],
|
|
691
920
|
),
|
|
692
|
-
input.
|
|
921
|
+
input.claudeConnections ?? {},
|
|
693
922
|
),
|
|
694
|
-
input.
|
|
923
|
+
input.workspaceClaudeConnections ?? {},
|
|
924
|
+
"workspace",
|
|
695
925
|
);
|
|
696
926
|
const providers = new Map(
|
|
697
927
|
configuredProviders(catalogSettings).map((provider) => [provider.id, provider]),
|
|
@@ -708,38 +938,62 @@ export function resolveWorkspaceModelSelection(
|
|
|
708
938
|
? input.credentialReadinessMaxAgeMs
|
|
709
939
|
: MODEL_CREDENTIAL_READINESS_OBSERVATION_MAX_AGE_MS;
|
|
710
940
|
|
|
711
|
-
return configuredModels(catalogSettings)
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
941
|
+
return configuredModels(catalogSettings)
|
|
942
|
+
.filter((model) => isModelAvailableForNewSelection(catalogSettings, model.id))
|
|
943
|
+
.map((model) => {
|
|
944
|
+
const provider = providers.get(model.providerId);
|
|
945
|
+
const verdict = evaluateWorkspaceModelPolicy(input.policy, {
|
|
715
946
|
providerId: model.providerId,
|
|
716
947
|
modelId: model.id,
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
948
|
+
chargesCredits: model.cost === "credits",
|
|
949
|
+
});
|
|
950
|
+
const allowedByConnections = modelAllowedByConnections(
|
|
951
|
+
input.connectionModelRestrictions ?? {},
|
|
952
|
+
model.id,
|
|
953
|
+
);
|
|
954
|
+
const policyAllowed = verdict.allowed && allowedByConnections;
|
|
955
|
+
// Name the credit switch only when it is the sole reason; an allowlist
|
|
956
|
+
// or connection restriction keeps the generic policy reason.
|
|
957
|
+
const creditsDisabled =
|
|
958
|
+
!verdict.allowed &&
|
|
959
|
+
verdict.reason === "credits" &&
|
|
960
|
+
allowedByConnections &&
|
|
961
|
+
input.policy != null &&
|
|
962
|
+
evaluateWorkspaceModelPolicy(
|
|
963
|
+
{ ...input.policy, allowCreditModels: true },
|
|
964
|
+
{ providerId: model.providerId, modelId: model.id, chargesCredits: true },
|
|
965
|
+
).allowed;
|
|
966
|
+
const credentialReadiness = credentialReadinessFor({
|
|
736
967
|
model,
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
968
|
+
provider,
|
|
969
|
+
codexSubscriptionActive: input.codexSubscriptionActive,
|
|
970
|
+
xaiSubscriptionActive: input.xaiSubscriptionActive === true,
|
|
971
|
+
workspaceGatewayConnectionActive: input.workspaceGatewayConnectionActive === true,
|
|
972
|
+
workspaceOpenRouterConnectionActive: input.workspaceOpenRouterConnectionActive === true,
|
|
973
|
+
workspaceOpperConnectionActive: input.workspaceOpperConnectionActive === true,
|
|
974
|
+
claudeConnections: input.claudeConnections,
|
|
975
|
+
workspaceClaudeConnections: input.workspaceClaudeConnections,
|
|
976
|
+
organizationGatewayConnectionActive: input.organizationGatewayConnectionActive === true,
|
|
977
|
+
organizationOpenRouterConnectionActive:
|
|
978
|
+
input.organizationOpenRouterConnectionActive === true,
|
|
979
|
+
organizationOpperConnectionActive: input.organizationOpperConnectionActive === true,
|
|
980
|
+
observation: input.credentialReadinessObservations?.[model.definitionVersion],
|
|
740
981
|
nowMs,
|
|
741
982
|
maxAgeMs,
|
|
742
|
-
})
|
|
743
|
-
|
|
744
|
-
|
|
983
|
+
});
|
|
984
|
+
return {
|
|
985
|
+
model,
|
|
986
|
+
credentialReadiness,
|
|
987
|
+
policyAllowed,
|
|
988
|
+
availability: availabilityFor({
|
|
989
|
+
model,
|
|
990
|
+
credentialReadiness,
|
|
991
|
+
policyAllowed,
|
|
992
|
+
creditsDisabled,
|
|
993
|
+
observation: input.observations?.[model.definitionVersion],
|
|
994
|
+
nowMs,
|
|
995
|
+
maxAgeMs,
|
|
996
|
+
}),
|
|
997
|
+
};
|
|
998
|
+
});
|
|
745
999
|
}
|