@opengeni/api-router 0.16.4 → 0.16.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createAppComposition,
3
3
  startSlackInteractionPump
4
- } from "./chunk-TFHWQL2W.js";
4
+ } from "./chunk-FGNCK7HE.js";
5
5
 
6
6
  // src/index.ts
7
7
  import {
@@ -32,6 +32,7 @@ export declare function buildWorkspaceModelCatalog(input: {
32
32
  settings: Settings;
33
33
  policy: WorkspaceModelPolicyContract | null;
34
34
  codexSubscriptionActive: boolean;
35
+ workspaceGatewayConnectionActive?: boolean;
35
36
  credentialReadinessObservations?: Readonly<Record<string, ModelCredentialReadinessObservation>> | undefined;
36
37
  observations?: Readonly<Record<string, ModelAvailabilityObservation>> | undefined;
37
38
  now?: Date | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/api-router",
3
- "version": "0.16.4",
3
+ "version": "0.16.5",
4
4
  "description": "OpenGeni HTTP surface: the Hono adapter/router (createApp), routes, MCP HTTP transport, and HTTP access adapters over @opengeni/core. An engine-distribution surface — its runtime closure includes engine-internal packages.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -44,17 +44,17 @@
44
44
  "@modelcontextprotocol/sdk": "^1.29.0",
45
45
  "@opengeni/agent-proto": "^0.3.0",
46
46
  "@opengeni/codex": "^0.2.9",
47
- "@opengeni/config": "^0.10.0",
48
- "@opengeni/contracts": "^0.31.0",
49
- "@opengeni/core": "^0.18.0",
50
- "@opengeni/db": "^0.22.1",
51
- "@opengeni/documents": "^0.2.69",
52
- "@opengeni/events": "^0.3.59",
53
- "@opengeni/github": "^0.4.16",
47
+ "@opengeni/config": "^0.10.1",
48
+ "@opengeni/contracts": "^0.31.1",
49
+ "@opengeni/core": "^0.18.1",
50
+ "@opengeni/db": "^0.22.2",
51
+ "@opengeni/documents": "^0.2.70",
52
+ "@opengeni/events": "^0.3.60",
53
+ "@opengeni/github": "^0.4.17",
54
54
  "@opengeni/network": "^0.1.1",
55
- "@opengeni/observability": "^0.4.3",
56
- "@opengeni/runtime": "^0.17.0",
57
- "@opengeni/storage": "^0.2.53",
55
+ "@opengeni/observability": "^0.4.4",
56
+ "@opengeni/runtime": "^0.17.1",
57
+ "@opengeni/storage": "^0.2.54",
58
58
  "@temporalio/client": "^1.17.0",
59
59
  "better-auth": "^1.6.14",
60
60
  "hono": "^4.12.18",
package/src/app.ts CHANGED
@@ -387,7 +387,7 @@ export function createAppComposition(deps: AppDependencies): {
387
387
  // Provider-grouped model list for the picker. configuredModels() carries the
388
388
  // union of the built-in allow-list and every registry provider's models, in
389
389
  // selection order (default model first); project each to the client-safe
390
- // ClientModel shape (ConfiguredModel.providerId ClientModel.provider).
390
+ // provider-blind ClientModel shape (execution topology remains server-side).
391
391
  models: configuredModels(catalogSettings).map(projectClientModel),
392
392
  defaultReasoningEffort: deps.settings.openaiReasoningEffort,
393
393
  allowedReasoningEfforts: configuredAllowedReasoningEfforts(deps.settings),
@@ -2,6 +2,7 @@ import {
2
2
  configuredModels,
3
3
  configuredProviders,
4
4
  withCodexCatalogProvider,
5
+ withWorkspaceGatewayCatalogProvider,
5
6
  type ConfiguredModel,
6
7
  type Settings,
7
8
  } from "@opengeni/config";
@@ -34,20 +35,30 @@ export const MODEL_CREDENTIAL_READINESS_OBSERVATION_MAX_AGE_MS = 5 * 60_000;
34
35
 
35
36
  /** Static, client-safe definition projection. No provider secret is reachable. */
36
37
  export function projectClientModel(model: ConfiguredModel): ClientModel {
38
+ const source =
39
+ model.credentialSource.kind === "connected_subscription"
40
+ ? "codex"
41
+ : model.credentialSource.kind === "workspace_connection"
42
+ ? "workspace_gateway"
43
+ : "opengeni";
44
+ const publicProvider =
45
+ source === "codex"
46
+ ? { provider: "codex", providerLabel: "Codex" }
47
+ : source === "workspace_gateway"
48
+ ? { provider: "workspace-gateway", providerLabel: "Your Gateway" }
49
+ : { provider: "opengeni", providerLabel: "OpenGeni" };
37
50
  return ClientModel.parse({
38
51
  id: model.id,
39
52
  label: model.label,
40
- provider: model.providerId,
41
- providerLabel: model.providerLabel,
53
+ ...publicProvider,
54
+ source,
42
55
  api: model.api,
43
56
  ...(model.contextWindowTokens === undefined
44
57
  ? {}
45
58
  : { contextWindowTokens: model.contextWindowTokens }),
46
59
  schemaVersion: model.schemaVersion,
47
60
  aliases: model.aliases,
48
- deployment: model.deployment,
49
61
  executionLimits: model.executionLimits,
50
- credentialSource: model.credentialSource,
51
62
  billing: model.billing,
52
63
  capabilities: model.capabilities,
53
64
  ...(model.pricing === undefined ? {} : { pricing: model.pricing }),
@@ -119,6 +130,7 @@ function credentialReadinessFor(input: {
119
130
  model: ConfiguredModel;
120
131
  provider: ReturnType<typeof configuredProviders>[number] | undefined;
121
132
  codexSubscriptionActive: boolean;
133
+ workspaceGatewayConnectionActive: boolean;
122
134
  observation: ModelCredentialReadinessObservation | undefined;
123
135
  nowMs: number;
124
136
  maxAgeMs: number;
@@ -134,6 +146,16 @@ function credentialReadinessFor(input: {
134
146
  checkedAt: null,
135
147
  };
136
148
  }
149
+ if (source.kind === "workspace_connection") {
150
+ return input.workspaceGatewayConnectionActive
151
+ ? { status: "ready", reason: null, basis: "connection", checkedAt: null }
152
+ : {
153
+ status: "not_ready",
154
+ reason: "needs_reauth",
155
+ basis: "connection",
156
+ checkedAt: null,
157
+ };
158
+ }
137
159
  if (source.kind === "deployment" && source.mechanism === "api_key") {
138
160
  return input.provider?.apiKey
139
161
  ? { status: "ready", reason: null, basis: "configuration", checkedAt: null }
@@ -146,7 +168,7 @@ function credentialReadinessFor(input: {
146
168
  }
147
169
  return observedCredentialReadiness({
148
170
  observation: input.observation,
149
- basis: source.kind === "workspace_connection" ? "connection" : "resolver",
171
+ basis: "resolver",
150
172
  nowMs: input.nowMs,
151
173
  maxAgeMs: input.maxAgeMs,
152
174
  });
@@ -286,6 +308,7 @@ export function buildWorkspaceModelCatalog(input: {
286
308
  settings: Settings;
287
309
  policy: WorkspaceModelPolicyContract | null;
288
310
  codexSubscriptionActive: boolean;
311
+ workspaceGatewayConnectionActive?: boolean;
289
312
  credentialReadinessObservations?:
290
313
  | Readonly<Record<string, ModelCredentialReadinessObservation>>
291
314
  | undefined;
@@ -293,9 +316,10 @@ export function buildWorkspaceModelCatalog(input: {
293
316
  now?: Date | undefined;
294
317
  credentialReadinessMaxAgeMs?: number | undefined;
295
318
  }): WorkspaceModelCatalogResponseType {
296
- const catalogSettings = input.settings.codexSubscriptionEnabled
319
+ const codexSettings = input.settings.codexSubscriptionEnabled
297
320
  ? withCodexCatalogProvider(input.settings)
298
321
  : input.settings;
322
+ const catalogSettings = withWorkspaceGatewayCatalogProvider(codexSettings);
299
323
  const providers = new Map(
300
324
  configuredProviders(catalogSettings).map((provider) => [provider.id, provider]),
301
325
  );
@@ -316,6 +340,7 @@ export function buildWorkspaceModelCatalog(input: {
316
340
  model,
317
341
  provider,
318
342
  codexSubscriptionActive: input.codexSubscriptionActive,
343
+ workspaceGatewayConnectionActive: input.workspaceGatewayConnectionActive === true,
319
344
  observation: input.credentialReadinessObservations?.[model.definitionVersion],
320
345
  nowMs,
321
346
  maxAgeMs,
@@ -37,6 +37,7 @@ import {
37
37
  updateWorkspaceSettings,
38
38
  upsertWorkspaceModelPolicy,
39
39
  workspaceCodexSubscriptionActive,
40
+ workspaceVercelAiGatewayConnectionActive,
40
41
  } from "@opengeni/db";
41
42
  import { boundWorkspaceControlHttpPage } from "@opengeni/events";
42
43
  import type { Hono } from "hono";
@@ -162,9 +163,10 @@ export function registerWorkspaceRoutes(app: Hono, deps: ApiRouteDeps): void {
162
163
  app.get("/v1/workspaces/:workspaceId/model-catalog", async (c) => {
163
164
  const workspaceId = c.req.param("workspaceId");
164
165
  await requireAccessGrant(c, deps, workspaceId, "workspace:read");
165
- const [policy, codexSubscriptionActive] = await Promise.all([
166
+ const [policy, codexSubscriptionActive, workspaceGatewayConnectionActive] = await Promise.all([
166
167
  getWorkspaceModelPolicy(deps.db, workspaceId),
167
168
  workspaceCodexSubscriptionActive(deps.db, deps.settings, workspaceId),
169
+ workspaceVercelAiGatewayConnectionActive(deps.db, workspaceId),
168
170
  ]);
169
171
  c.header("cache-control", "private, no-store");
170
172
  return c.json(
@@ -173,6 +175,7 @@ export function registerWorkspaceRoutes(app: Hono, deps: ApiRouteDeps): void {
173
175
  settings: deps.settings,
174
176
  policy,
175
177
  codexSubscriptionActive,
178
+ workspaceGatewayConnectionActive,
176
179
  }),
177
180
  ),
178
181
  );