@opengeni/core 4.0.3 → 4.0.4-canary.36239117573001

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
@@ -220,22 +220,22 @@ async function requireLiveAgentAttemptAuthorization(db, grant, callerSessionId)
220
220
  async function requireSessionAuthorization(deps, grant, input) {
221
221
  const port = deps.sessionAuthorization;
222
222
  const isAgentAttempt = grantHasAgentAttemptAuthority(grant);
223
- const [slackAccess, authority] = await Promise.all([
224
- getSlackInteractionSessionAccessForSession(deps.db, {
225
- accountId: grant.accountId,
226
- workspaceId: grant.workspaceId,
227
- sessionId: input.sessionId
228
- }),
229
- getSessionAuthorityProjection(deps.db, grant.workspaceId, input.sessionId)
230
- ]);
223
+ const slackAccess = await getSlackInteractionSessionAccessForSession(deps.db, {
224
+ accountId: grant.accountId,
225
+ workspaceId: grant.workspaceId,
226
+ sessionId: input.sessionId
227
+ });
228
+ const authority = await getSessionAuthorityProjection(
229
+ deps.db,
230
+ grant.workspaceId,
231
+ input.sessionId
232
+ );
231
233
  if (!port && !isAgentAttempt && slackAccess?.visibility !== "private" && authority?.visibility !== "user_private") {
232
234
  return null;
233
235
  }
234
236
  if (!authority) throw new SessionAuthorizationDeniedError("not_found");
235
- const [resolvedActor, resolvedTarget] = await Promise.all([
236
- resolveSessionAuthorizationActor(deps.db, grant),
237
- resolveSessionAuthorizationTarget(deps.db, grant, input.sessionId)
238
- ]);
237
+ const resolvedActor = await resolveSessionAuthorizationActor(deps.db, grant);
238
+ const resolvedTarget = await resolveSessionAuthorizationTarget(deps.db, grant, input.sessionId);
239
239
  const actor = resolvedActor.actor;
240
240
  const target = resolvedTarget.target;
241
241
  const agentRelatedSessionAccess = actor.kind === "agent_attempt" ? relatedSessionAccessForAgentAttempt(actor, target.sessionId) : null;
@@ -357,10 +357,8 @@ async function resolveSessionAuthorizationActor(db, grant) {
357
357
  if (typeof callerSessionId !== "string" || typeof turnId !== "string" || typeof attemptId !== "string" || typeof executionGeneration !== "number" || !Number.isSafeInteger(executionGeneration) || executionGeneration < 1) {
358
358
  throw new SessionAuthorizationDeniedError("caller_stale");
359
359
  }
360
- const [callerSession, turn] = await Promise.all([
361
- getSession(db, grant.workspaceId, callerSessionId),
362
- getSessionTurnForAttempt(db, grant.workspaceId, callerSessionId, attemptId)
363
- ]);
360
+ const callerSession = await getSession(db, grant.workspaceId, callerSessionId);
361
+ const turn = await getSessionTurnForAttempt(db, grant.workspaceId, callerSessionId, attemptId);
364
362
  if (!callerSession || callerSession.accountId !== grant.accountId || !turn || turn.id !== turnId || turn.executionGeneration !== executionGeneration || callerSession.activeTurnId !== turn.id) {
365
363
  throw new SessionAuthorizationDeniedError("caller_stale");
366
364
  }
@@ -2323,6 +2321,270 @@ function resolveWorkspaceModelSelection(input) {
2323
2321
  });
2324
2322
  }
2325
2323
 
2324
+ // src/default-session-model.ts
2325
+ import {
2326
+ canonicalizeConfiguredModelId
2327
+ } from "@opengeni/config";
2328
+ import {
2329
+ resolveWorkspaceSessionDefaults
2330
+ } from "@opengeni/contracts";
2331
+ import {
2332
+ getScheduledTaskXaiProviderAccountAuthoritySnapshot,
2333
+ getSession as getSession2,
2334
+ getWorkspace,
2335
+ getWorkspaceConnectionModelRestrictions,
2336
+ getWorkspaceModelPolicy,
2337
+ listOrganizationModelProviderCustomModelsForWorkspace as listOrganizationModelProviderCustomModelsForWorkspace2,
2338
+ listWorkspaceGatewayCustomModels as listWorkspaceGatewayCustomModels2,
2339
+ listWorkspaceOpenRouterCustomModels as listWorkspaceOpenRouterCustomModels2,
2340
+ organizationModelProviderConnectionActiveForWorkspace,
2341
+ workspaceCodexSubscriptionActive,
2342
+ workspaceOpenRouterConnectionActive,
2343
+ workspaceVercelAiGatewayConnectionActive,
2344
+ organizationHoldsCredits,
2345
+ workspaceXaiSubscriptionActive,
2346
+ workspaceXaiSubscriptionActiveForAuthority,
2347
+ XaiAuthorityPoolInactiveError
2348
+ } from "@opengeni/db";
2349
+ var REASONING_EFFORT_ORDER = [
2350
+ "none",
2351
+ "minimal",
2352
+ "low",
2353
+ "medium",
2354
+ "high",
2355
+ "xhigh",
2356
+ "max"
2357
+ ];
2358
+ function supportedReasoningEfforts(model) {
2359
+ const efforts = model.capabilities.reasoning.efforts;
2360
+ return REASONING_EFFORT_ORDER.filter((effort) => efforts.includes(effort));
2361
+ }
2362
+ function defaultReasoningEffortForConfiguredModel(model, fallback) {
2363
+ const options = supportedReasoningEfforts(model);
2364
+ if (options.length === 0) return fallback;
2365
+ const configured = model.capabilities.reasoning.defaultEffort;
2366
+ if (configured && options.includes(configured)) return configured;
2367
+ return options[0];
2368
+ }
2369
+ function clampReasoningEffortForConfiguredModel(model, preferred, fallback) {
2370
+ const options = supportedReasoningEfforts(model);
2371
+ if (options.length === 0) return fallback;
2372
+ if (options.includes(preferred)) return preferred;
2373
+ const ceiling = REASONING_EFFORT_ORDER.indexOf(preferred);
2374
+ const below = options.filter((effort) => REASONING_EFFORT_ORDER.indexOf(effort) <= ceiling);
2375
+ return below.at(-1) ?? defaultReasoningEffortForConfiguredModel(model, fallback);
2376
+ }
2377
+ function findSelection(selections, modelId) {
2378
+ return selections.find((selection) => selection.model.id === modelId) ?? selections.find((selection) => selection.model.aliases.includes(modelId));
2379
+ }
2380
+ function creditsCandidate(input) {
2381
+ const fallbackEffort = input.settings.openaiReasoningEffort;
2382
+ const deployment = findSelection(input.selections, input.settings.openaiModel);
2383
+ if (deployment?.availability.selectable && deployment.model.cost === "credits") return null;
2384
+ const configured = findSelection(input.selections, input.settings.creditsDefaultModel);
2385
+ if (configured?.availability.selectable && configured.model.cost === "credits") {
2386
+ return {
2387
+ model: configured.model.id,
2388
+ reasoningEffort: clampReasoningEffortForConfiguredModel(
2389
+ configured.model,
2390
+ input.settings.creditsDefaultReasoningEffort,
2391
+ fallbackEffort
2392
+ ),
2393
+ source: "credits"
2394
+ };
2395
+ }
2396
+ const first = input.selections.find(
2397
+ (selection) => selection.availability.selectable && selection.model.cost === "credits"
2398
+ );
2399
+ return first ? {
2400
+ model: first.model.id,
2401
+ reasoningEffort: defaultReasoningEffortForConfiguredModel(first.model, fallbackEffort),
2402
+ source: "credits"
2403
+ } : null;
2404
+ }
2405
+ function selectDefaultSessionModel(input) {
2406
+ const fallbackEffort = input.settings.openaiReasoningEffort;
2407
+ if (input.workspaceDefaults) {
2408
+ const saved = findSelection(input.selections, input.workspaceDefaults.model);
2409
+ if (saved?.availability.selectable) {
2410
+ return {
2411
+ model: saved.model.id,
2412
+ reasoningEffort: clampReasoningEffortForConfiguredModel(
2413
+ saved.model,
2414
+ input.workspaceDefaults.reasoningEffort,
2415
+ fallbackEffort
2416
+ ),
2417
+ source: "workspace"
2418
+ };
2419
+ }
2420
+ }
2421
+ const deployment = findSelection(input.selections, input.settings.openaiModel);
2422
+ const subscription = deployment?.availability.selectable && deployment.model.cost === "subscription" ? deployment : input.selections.find(
2423
+ (selection) => selection.availability.selectable && selection.model.cost === "subscription"
2424
+ );
2425
+ if (subscription) {
2426
+ return {
2427
+ model: subscription.model.id,
2428
+ reasoningEffort: defaultReasoningEffortForConfiguredModel(subscription.model, fallbackEffort),
2429
+ source: "subscription"
2430
+ };
2431
+ }
2432
+ if (input.creditsAvailable) {
2433
+ const credits = creditsCandidate(input);
2434
+ if (credits) return credits;
2435
+ }
2436
+ return {
2437
+ model: deployment?.model.id ?? canonicalizeConfiguredModelId(input.settings, input.settings.openaiModel),
2438
+ reasoningEffort: fallbackEffort,
2439
+ source: "deployment"
2440
+ };
2441
+ }
2442
+ function creditsDefaultSessionModel(input) {
2443
+ if (input.settings.billingMode !== "stripe") return null;
2444
+ return selectDefaultSessionModel({
2445
+ settings: input.settings,
2446
+ selections: input.selections,
2447
+ workspaceDefaults: resolveWorkspaceSessionDefaults(input.workspaceSettings),
2448
+ creditsAvailable: true
2449
+ });
2450
+ }
2451
+ async function resolveDefaultSessionModelForSelections(db, input) {
2452
+ const decision = {
2453
+ settings: input.settings,
2454
+ selections: input.selections,
2455
+ workspaceDefaults: resolveWorkspaceSessionDefaults(input.workspaceSettings)
2456
+ };
2457
+ const withoutCredits = selectDefaultSessionModel({ ...decision, creditsAvailable: false });
2458
+ if (withoutCredits.source !== "deployment" || input.settings.billingMode !== "stripe" || creditsCandidate(decision) === null) {
2459
+ return withoutCredits;
2460
+ }
2461
+ return await organizationHoldsCredits(db, input.accountId) ? selectDefaultSessionModel({ ...decision, creditsAvailable: true }) : withoutCredits;
2462
+ }
2463
+ async function connectionRestrictionsAndXaiReadiness(db, settings, context) {
2464
+ const { workspaceId, subjectId, xaiAuthoritySnapshot } = context;
2465
+ if (!xaiAuthoritySnapshot) {
2466
+ const [restrictions2, xaiSubscriptionActive] = await Promise.all([
2467
+ getWorkspaceConnectionModelRestrictions(db, workspaceId, subjectId),
2468
+ workspaceXaiSubscriptionActive(db, settings, workspaceId, subjectId)
2469
+ ]);
2470
+ return { restrictions: restrictions2, xaiSubscriptionActive };
2471
+ }
2472
+ const frozen = await Promise.allSettled([
2473
+ getWorkspaceConnectionModelRestrictions(db, workspaceId, subjectId, xaiAuthoritySnapshot),
2474
+ workspaceXaiSubscriptionActiveForAuthority(db, settings, {
2475
+ workspaceId,
2476
+ subjectId,
2477
+ authoritySnapshot: xaiAuthoritySnapshot
2478
+ })
2479
+ ]);
2480
+ const [restrictions, readiness] = frozen;
2481
+ if (restrictions.status === "fulfilled" && readiness.status === "fulfilled") {
2482
+ return { restrictions: restrictions.value, xaiSubscriptionActive: readiness.value };
2483
+ }
2484
+ for (const result of frozen) {
2485
+ if (result.status === "rejected" && !(result.reason instanceof XaiAuthorityPoolInactiveError)) {
2486
+ throw result.reason;
2487
+ }
2488
+ }
2489
+ const current = await getWorkspaceConnectionModelRestrictions(db, workspaceId, subjectId);
2490
+ return {
2491
+ restrictions: { ...current, "supergrok/": [] },
2492
+ xaiSubscriptionActive: false
2493
+ };
2494
+ }
2495
+ async function loadWorkspaceModelSelectionInput(db, settings, context) {
2496
+ const { accountId, workspaceId } = context;
2497
+ const [
2498
+ { restrictions: connectionModelRestrictions, xaiSubscriptionActive },
2499
+ policy,
2500
+ codexSubscriptionActive,
2501
+ workspaceGatewayConnectionActive,
2502
+ workspaceGatewayCustomModels,
2503
+ openRouterConnectionActive,
2504
+ workspaceOpenRouterCustomModels,
2505
+ organizationGatewayConnectionActive,
2506
+ organizationOpenRouterConnectionActive,
2507
+ organizationGatewayCustomModels,
2508
+ organizationOpenRouterCustomModels
2509
+ ] = await Promise.all([
2510
+ connectionRestrictionsAndXaiReadiness(db, settings, context),
2511
+ getWorkspaceModelPolicy(db, workspaceId),
2512
+ workspaceCodexSubscriptionActive(db, settings, workspaceId),
2513
+ workspaceVercelAiGatewayConnectionActive(db, workspaceId),
2514
+ listWorkspaceGatewayCustomModels2(db, { accountId, workspaceId }),
2515
+ workspaceOpenRouterConnectionActive(db, workspaceId),
2516
+ listWorkspaceOpenRouterCustomModels2(db, { accountId, workspaceId }),
2517
+ organizationModelProviderConnectionActiveForWorkspace(db, {
2518
+ accountId,
2519
+ workspaceId,
2520
+ providerKind: "vercel_gateway"
2521
+ }),
2522
+ organizationModelProviderConnectionActiveForWorkspace(db, {
2523
+ accountId,
2524
+ workspaceId,
2525
+ providerKind: "openrouter"
2526
+ }),
2527
+ listOrganizationModelProviderCustomModelsForWorkspace2(db, {
2528
+ accountId,
2529
+ workspaceId,
2530
+ providerKind: "vercel_gateway"
2531
+ }),
2532
+ listOrganizationModelProviderCustomModelsForWorkspace2(db, {
2533
+ accountId,
2534
+ workspaceId,
2535
+ providerKind: "openrouter"
2536
+ })
2537
+ ]);
2538
+ return {
2539
+ connectionModelRestrictions,
2540
+ settings,
2541
+ policy,
2542
+ codexSubscriptionActive,
2543
+ xaiSubscriptionActive,
2544
+ workspaceGatewayConnectionActive,
2545
+ workspaceGatewayCustomModels,
2546
+ workspaceOpenRouterConnectionActive: openRouterConnectionActive,
2547
+ workspaceOpenRouterCustomModels,
2548
+ organizationGatewayConnectionActive,
2549
+ organizationOpenRouterConnectionActive,
2550
+ organizationGatewayCustomModels,
2551
+ organizationOpenRouterCustomModels
2552
+ };
2553
+ }
2554
+ async function resolveDefaultSessionModel(db, settings, context) {
2555
+ const [selectionInput, workspaceSettings] = await Promise.all([
2556
+ loadWorkspaceModelSelectionInput(db, settings, context),
2557
+ context.workspaceSettings !== void 0 ? Promise.resolve(context.workspaceSettings) : getWorkspace(db, context.workspaceId).then((workspace) => workspace?.settings ?? {})
2558
+ ]);
2559
+ return await resolveDefaultSessionModelForSelections(db, {
2560
+ settings,
2561
+ accountId: context.accountId,
2562
+ workspaceSettings,
2563
+ selections: resolveWorkspaceModelSelection(selectionInput)
2564
+ });
2565
+ }
2566
+ async function resolveScheduledTaskDefaultModel(db, settings, task) {
2567
+ return await resolveDefaultSessionModel(db, settings, {
2568
+ accountId: task.accountId,
2569
+ workspaceId: task.workspaceId,
2570
+ subjectId: task.ownerSubjectId ?? task.createdBy.subjectId,
2571
+ xaiAuthoritySnapshot: await getScheduledTaskXaiProviderAccountAuthoritySnapshot(
2572
+ db,
2573
+ task.workspaceId,
2574
+ task.id
2575
+ )
2576
+ });
2577
+ }
2578
+ async function resolveScheduledTaskPreflightModel(db, settings, task) {
2579
+ if (task.agentConfig.model) return task.agentConfig.model;
2580
+ const targetSessionId = task.runMode === "existing_session" ? task.targetSessionId : task.runMode === "reusable_session" ? task.reusableSessionId : null;
2581
+ if (targetSessionId) {
2582
+ const session = await getSession2(db, task.workspaceId, targetSessionId);
2583
+ if (session) return session.model;
2584
+ }
2585
+ return (await resolveScheduledTaskDefaultModel(db, settings, task)).model;
2586
+ }
2587
+
2326
2588
  // src/sandbox/fleet.ts
2327
2589
  import {
2328
2590
  authorizePersonalMachineForAttempt,
@@ -4024,7 +4286,7 @@ function sessionCreationMetadata(metadata) {
4024
4286
 
4025
4287
  // src/domain/sessions.ts
4026
4288
  import {
4027
- canonicalizeConfiguredModelId,
4289
+ canonicalizeConfiguredModelId as canonicalizeConfiguredModelId2,
4028
4290
  configuredAllowedModels,
4029
4291
  withCodexCatalogProvider as withCodexCatalogProvider2,
4030
4292
  ORGANIZATION_GATEWAY_MODEL_ID_PREFIX as ORGANIZATION_GATEWAY_MODEL_ID_PREFIX2,
@@ -4034,7 +4296,8 @@ import {
4034
4296
  resolveTurnExecutionPolicyV1,
4035
4297
  WORKSPACE_GATEWAY_MODEL_ID_PREFIX as WORKSPACE_GATEWAY_MODEL_ID_PREFIX2,
4036
4298
  WORKSPACE_OPENROUTER_MODEL_ID_PREFIX as WORKSPACE_OPENROUTER_MODEL_ID_PREFIX2,
4037
- XAI_SUBSCRIPTION_MODEL_ID_PREFIX
4299
+ XAI_SUBSCRIPTION_MODEL_ID_PREFIX,
4300
+ codeSearchDeploymentPolicy
4038
4301
  } from "@opengeni/config";
4039
4302
  import {
4040
4303
  AUTOMATIC_SESSION_TITLE_FALLBACK,
@@ -4075,7 +4338,7 @@ import {
4075
4338
  listEnabledMcpCapabilityServers as listEnabledMcpCapabilityServers2,
4076
4339
  requireApprovalWithFloor,
4077
4340
  getSandbox as getSandbox3,
4078
- getSession as getSession2,
4341
+ getSession as getSession3,
4079
4342
  getInitializedSessionCreateReplay,
4080
4343
  getSessionAuthorityProjection as getSessionAuthorityProjection4,
4081
4344
  SessionIdConflictError,
@@ -4086,7 +4349,7 @@ import {
4086
4349
  getSessionTurnForAttempt as getSessionTurnForAttempt3,
4087
4350
  getSessionTurnPersonalConnectionDelegations as getSessionTurnPersonalConnectionDelegations2,
4088
4351
  getSessionTurnXaiProviderAccountAuthoritySnapshot,
4089
- getWorkspaceModelPolicy,
4352
+ getWorkspaceModelPolicy as getWorkspaceModelPolicy2,
4090
4353
  requireWorkspace as requireWorkspace4,
4091
4354
  initializeSessionStartAtomically,
4092
4355
  listSessionTurns,
@@ -4205,6 +4468,7 @@ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/
4205
4468
  import { isDeepStrictEqual } from "util";
4206
4469
  import { withLockedCapabilityInstallation } from "@opengeni/db/capability-reconciliation";
4207
4470
  import { environmentsEncryptionKeyBytes as environmentsEncryptionKeyBytes2 } from "@opengeni/config";
4471
+ import { pinnedFetch } from "@opengeni/network";
4208
4472
  import {
4209
4473
  CapabilityCatalogItem,
4210
4474
  capabilityCatalogItemIsTrustedForExposure,
@@ -4478,7 +4742,12 @@ async function prepareCapabilityEnable(input) {
4478
4742
  assertRequiredMcpCredentialHeaders(item, headers, connectionRef);
4479
4743
  installationMetadata = {
4480
4744
  ...installationMetadata,
4481
- ...connectionRef && !headers ? authDeferredMcpConnectivity() : await validateMcpCapabilityConnection(item, input.probeMcpServer, headers ?? void 0)
4745
+ ...connectionRef && !headers ? authDeferredMcpConnectivity() : await validateMcpCapabilityConnection(
4746
+ item,
4747
+ input.probeMcpServer,
4748
+ headers ?? void 0,
4749
+ input.settings
4750
+ )
4482
4751
  };
4483
4752
  if (connectionRef) {
4484
4753
  installationConfig.connectionRef = connectionRef;
@@ -4725,7 +4994,7 @@ function requireCapabilityHeaderEncryption(settings) {
4725
4994
  }
4726
4995
  return key;
4727
4996
  }
4728
- async function validateMcpCapabilityConnection(item, probe = probeStreamableHttpMcpServer, headers) {
4997
+ async function validateMcpCapabilityConnection(item, probe = probeStreamableHttpMcpServer, headers, settings) {
4729
4998
  if (item.kind !== "mcp") {
4730
4999
  return {};
4731
5000
  }
@@ -4740,7 +5009,8 @@ async function validateMcpCapabilityConnection(item, probe = probeStreamableHttp
4740
5009
  name: item.name,
4741
5010
  url: item.endpointUrl,
4742
5011
  timeoutMs: mcpCapabilityProbeTimeoutMs,
4743
- ...headers ? { headers } : {}
5012
+ ...headers ? { headers } : {},
5013
+ ...settings ? { settings } : {}
4744
5014
  });
4745
5015
  return {
4746
5016
  mcpConnectivity: {
@@ -4756,6 +5026,8 @@ async function validateMcpCapabilityConnection(item, probe = probeStreamableHttp
4756
5026
  }
4757
5027
  }
4758
5028
  async function probeStreamableHttpMcpServer(input) {
5029
+ const settings = input.settings;
5030
+ if (!settings) throw new Error("Network policy is unavailable for MCP validation");
4759
5031
  const controller = new AbortController();
4760
5032
  const timeout = setTimeout(() => controller.abort(), input.timeoutMs);
4761
5033
  const client = new Client(
@@ -4767,7 +5039,11 @@ async function probeStreamableHttpMcpServer(input) {
4767
5039
  requestInit: {
4768
5040
  signal: controller.signal,
4769
5041
  ...input.headers ? { headers: input.headers } : {}
4770
- }
5042
+ },
5043
+ fetch: (url, init) => pinnedFetch(url, init, settings, {
5044
+ label: "MCP capability probe",
5045
+ requireHttpsOutsideLocalTest: true
5046
+ })
4771
5047
  });
4772
5048
  await client.connect(transport, {
4773
5049
  timeout: input.timeoutMs,
@@ -6460,18 +6736,18 @@ async function listOwnConnectionAccountsForGrant(db, grant) {
6460
6736
  }
6461
6737
  async function listOwnConnectionMetadata(db, input) {
6462
6738
  const accounts = await listOwnedConnectionAccounts(db, input);
6463
- const connections = await Promise.all(
6464
- accounts.map(async (account) => {
6465
- const connection = await getConnectionMetadata2(
6466
- db,
6467
- account.originWorkspaceId,
6468
- account.connectionId,
6469
- input.subjectId
6470
- );
6471
- return connection?.accountId === input.accountId && connection.subjectId === input.subjectId && connection.authorityId != null && connection.status === "active" ? connection : null;
6472
- })
6473
- );
6474
- return connections.filter((connection) => connection !== null);
6739
+ const connections = [];
6740
+ for (const account of accounts) {
6741
+ const connection = await getConnectionMetadata2(
6742
+ db,
6743
+ account.originWorkspaceId,
6744
+ account.connectionId,
6745
+ input.subjectId
6746
+ );
6747
+ if (connection?.accountId === input.accountId && connection.subjectId === input.subjectId && connection.authorityId != null && connection.status === "active")
6748
+ connections.push(connection);
6749
+ }
6750
+ return connections;
6475
6751
  }
6476
6752
  async function authorizedSocialConnectionsForGrant(input) {
6477
6753
  const workspace = await listSocialConnections2(
@@ -8030,6 +8306,7 @@ async function createAndStartSessionWithOutcome(input) {
8030
8306
  ...input.scopeSubjectId !== void 0 ? { scopeSubjectId: input.scopeSubjectId } : {},
8031
8307
  ...input.memoryScope ? { memoryScope: input.memoryScope } : {},
8032
8308
  parentSessionId: input.parentSessionId ?? null,
8309
+ ...input.codeSearchDeploymentPolicy ? { codeSearchDeploymentPolicy: input.codeSearchDeploymentPolicy } : {},
8033
8310
  sandboxGroupId: input.sandboxGroupId ?? null,
8034
8311
  ...input.sandboxOs ? { sandboxOs: input.sandboxOs } : {},
8035
8312
  mcpServers: input.mcpServers ?? [],
@@ -8154,7 +8431,7 @@ function canonicalConfiguredModel(settings, model) {
8154
8431
  if (model === null || model === void 0) {
8155
8432
  return model;
8156
8433
  }
8157
- const canonicalModel = canonicalizeConfiguredModelId(settings, model);
8434
+ const canonicalModel = canonicalizeConfiguredModelId2(settings, model);
8158
8435
  if (canonicalModel.startsWith(CODEX_MODEL_ID_PREFIX) && settings.resolvedCodexModelsJson !== void 0) {
8159
8436
  if (settings.codexSubscriptionEnabled && configuredAllowedModels(withCodexCatalogProvider2(settings)).includes(canonicalModel)) {
8160
8437
  return canonicalModel;
@@ -8201,7 +8478,7 @@ async function assertWorkspaceModelPolicyAllows(db, settings, workspaceId, model
8201
8478
  if (canonicalModel === null || canonicalModel === void 0) {
8202
8479
  return;
8203
8480
  }
8204
- const policy = await getWorkspaceModelPolicy(db, workspaceId);
8481
+ const policy = await getWorkspaceModelPolicy2(db, workspaceId);
8205
8482
  if (!policy) {
8206
8483
  return;
8207
8484
  }
@@ -8683,7 +8960,7 @@ async function createSessionForRequestInFileScope(unresolvedDeps, grant, workspa
8683
8960
  throw error;
8684
8961
  }
8685
8962
  }
8686
- const parentSession = parentSessionId ? await getSession2(db, workspaceId, parentSessionId) : null;
8963
+ const parentSession = parentSessionId ? await getSession3(db, workspaceId, parentSessionId) : null;
8687
8964
  if (parentSessionId && !parentSession) {
8688
8965
  throw new HTTPException15(404, {
8689
8966
  message: `parent session not found in workspace: ${parentSessionId}`
@@ -8750,6 +9027,7 @@ async function createSessionForRequestInFileScope(unresolvedDeps, grant, workspa
8750
9027
  }
8751
9028
  const replayManagedHumanSubjectId = creationInitiator.actor ? parentCallingTurn?.initiatingHumanSubjectId ?? (parentCallingTurn?.initiator.kind === "subject" ? parentCallingTurn.initiator.subjectId : null) : authorization?.canonicalManagedHumanSession || grant.principalKind === "human_session" ? grant.subjectId : null;
8752
9029
  let retainedKeyedShellModel = null;
9030
+ let retainedKeyedShellReasoningEffort = null;
8753
9031
  if (payload.idempotencyKey && (effectiveVisibility !== "user_private" || replayManagedHumanSubjectId !== null)) {
8754
9032
  try {
8755
9033
  const initializedReplay = await getInitializedSessionCreateReplay(db, {
@@ -8774,6 +9052,7 @@ async function createSessionForRequestInFileScope(unresolvedDeps, grant, workspa
8774
9052
  }
8775
9053
  if (initializedReplay.outcome === "pending") {
8776
9054
  retainedKeyedShellModel = initializedReplay.session.model;
9055
+ retainedKeyedShellReasoningEffort = initializedReplay.session.reasoningEffort;
8777
9056
  } else {
8778
9057
  if (initializedReplay.workflowWakeRevision !== null) {
8779
9058
  await unresolvedDeps.workflowClient.wakeSessionWorkflow({
@@ -8831,7 +9110,13 @@ async function createSessionForRequestInFileScope(unresolvedDeps, grant, workspa
8831
9110
  payload.personalResourceAttachment,
8832
9111
  false
8833
9112
  );
8834
- const inheritedModel = parentCallingTurn?.model ?? parentSession?.model ?? settings.openaiModel;
9113
+ const resolvedDefault = parentSession || payload.model !== void 0 ? null : retainedKeyedShellModel !== null && retainedKeyedShellReasoningEffort !== null ? { model: retainedKeyedShellModel, reasoningEffort: retainedKeyedShellReasoningEffort } : await resolveDefaultSessionModel(db, settings, {
9114
+ accountId: grant.accountId,
9115
+ workspaceId,
9116
+ subjectId: grant.subjectId,
9117
+ workspaceSettings: workspace.settings
9118
+ });
9119
+ const inheritedModel = parentCallingTurn?.model ?? parentSession?.model ?? resolvedDefault?.model ?? settings.openaiModel;
8835
9120
  const effectiveModelId = payload.model ?? inheritedModel;
8836
9121
  const effectiveCatalogSettings = await resolveWorkspaceModelBoundarySettings(
8837
9122
  deps,
@@ -9085,7 +9370,7 @@ async function createSessionForRequestInFileScope(unresolvedDeps, grant, workspa
9085
9370
  throw new Error("effective session model unexpectedly resolved to null");
9086
9371
  }
9087
9372
  await assertWorkspaceModelPolicyAllows(db, settings, workspaceId, model);
9088
- const inheritedReasoningEffort = parentCallingTurn?.reasoningEffort ?? parentSession?.reasoningEffort ?? settings.openaiReasoningEffort;
9373
+ const inheritedReasoningEffort = parentCallingTurn?.reasoningEffort ?? parentSession?.reasoningEffort ?? resolvedDefault?.reasoningEffort ?? settings.openaiReasoningEffort;
9089
9374
  const inheritedLatencyMode = parentCallingTurn?.latencyMode ?? parentSession?.latencyMode ?? "standard";
9090
9375
  const reasoningEffort = payload.reasoningEffort ?? inheritedReasoningEffort;
9091
9376
  const latencyMode = payload.latencyMode ?? inheritedLatencyMode;
@@ -9373,6 +9658,7 @@ async function createSessionForRequestInFileScope(unresolvedDeps, grant, workspa
9373
9658
  db,
9374
9659
  bus,
9375
9660
  workflowClient,
9661
+ codeSearchDeploymentPolicy: codeSearchDeploymentPolicy(deps.settings),
9376
9662
  accountId: grant.accountId,
9377
9663
  workspaceId,
9378
9664
  visibility: effectiveVisibility,
@@ -10229,7 +10515,7 @@ async function readSessionLineage(deps, grant, sessionId) {
10229
10515
  surface: "core"
10230
10516
  });
10231
10517
  if (authorization?.relatedSessionAccess === "target") {
10232
- const session = await getSession2(deps.db, grant.workspaceId, sessionId);
10518
+ const session = await getSession3(deps.db, grant.workspaceId, sessionId);
10233
10519
  if (!session) {
10234
10520
  throw new HTTPException15(404, { message: "session not found" });
10235
10521
  }
@@ -10271,6 +10557,39 @@ async function acceptSessionUserMessageWithOutcome(...args) {
10271
10557
  return withSessionRlsActorContext4(actor, () => acceptSessionUserMessageInFileScope(...args));
10272
10558
  }
10273
10559
 
10560
+ // src/domain/session-native-connection-replacement.ts
10561
+ import { connectionMetadataMatchesBinding } from "@opengeni/db/session-mcp-credential-rotation";
10562
+ function nativeSessionConnectionReplacement(input) {
10563
+ const connection = input.connections.find(
10564
+ (candidate) => candidate.id === input.nativeConnectionId
10565
+ );
10566
+ if (!connection || connection.accountId !== input.accountId || connection.status !== "active" || (connection.subjectId === null ? connection.workspaceId !== input.workspaceId : !input.subjectId || connection.subjectId !== input.subjectId || !connection.authorityId)) {
10567
+ throw new Error("native connection unavailable");
10568
+ }
10569
+ const {
10570
+ authoritySource: _authoritySource,
10571
+ hostBinding: _hostBinding,
10572
+ accountSelection: _accountSelection,
10573
+ ...retained
10574
+ } = input.currentRef ?? {};
10575
+ if (input.currentRef && input.currentRef.providerDomain.toLowerCase() !== connection.providerDomain.toLowerCase())
10576
+ throw new Error("native connection provider mismatch");
10577
+ const ref = {
10578
+ ...retained,
10579
+ ...!input.currentRef?.resource && typeof connection.metadata.resource === "string" ? { resource: connection.metadata.resource } : {},
10580
+ connectionId: connection.id,
10581
+ providerDomain: connection.providerDomain,
10582
+ kind: connection.kind,
10583
+ subjectScope: connection.subjectId === null ? "workspace" : "subject"
10584
+ };
10585
+ const destination = input.replacementServerUrl ?? input.serverUrl;
10586
+ if (input.replacementServerUrl && (typeof connection.metadata.mcpUrl !== "string" || !connection.metadata.mcpUrl.trim()))
10587
+ throw new Error("native connection destination unavailable");
10588
+ if (!connectionMetadataMatchesBinding(connection, ref, destination))
10589
+ throw new Error("native connection binding mismatch");
10590
+ return ref;
10591
+ }
10592
+
10274
10593
  // src/application/session-mcp-credential-rotation.ts
10275
10594
  function sessionMcpRotationFingerprint(key, scope, request) {
10276
10595
  return {
@@ -10302,9 +10621,14 @@ async function rotateSessionMcpCredentialsForRequest(deps, authorization, sessio
10302
10621
  id: update.id,
10303
10622
  expectedCredentialVersion: update.expectedCredentialVersion,
10304
10623
  expectedServerUrl: update.expectedServerUrl,
10305
- headers: Object.fromEntries(
10306
- Object.entries(normalizedSessionMcpCredentialHeaders(update.headers)).map(([name, value]) => [name.toLowerCase(), value]).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0)
10307
- )
10624
+ ..."nativeConnectionId" in update ? {
10625
+ nativeConnectionId: update.nativeConnectionId,
10626
+ ...update.replacementServerUrl ? { replacementServerUrl: update.replacementServerUrl } : {}
10627
+ } : {
10628
+ headers: Object.fromEntries(
10629
+ Object.entries(normalizedSessionMcpCredentialHeaders(update.headers)).map(([name, value]) => [name.toLowerCase(), value]).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0)
10630
+ )
10631
+ }
10308
10632
  })).sort((left, right) => left.id < right.id ? -1 : left.id > right.id ? 1 : 0)
10309
10633
  };
10310
10634
  if (new Set(request.updates.map((update) => update.id)).size !== request.updates.length)
@@ -10320,20 +10644,43 @@ async function rotateSessionMcpCredentialsForRequest(deps, authorization, sessio
10320
10644
  actorType: grant.principalKind === "service" ? "service" : "human"
10321
10645
  };
10322
10646
  const externalAuthorize = externalContinuationCommitAuthorizer(authorization);
10647
+ let authorizedGrant = grant;
10323
10648
  try {
10324
10649
  return await rotateSessionMcpCredentialsAtomically(deps.db, {
10325
10650
  ...scope,
10326
10651
  operationKey: request.operationKey,
10327
10652
  ...sessionMcpRotationFingerprint(encryptionKey, scope, request),
10328
- updates: request.updates.map(({ headers, ...update }) => ({
10329
- ...update,
10330
- headersEncrypted: Object.fromEntries(
10331
- Object.entries(headers).map(([name, value]) => [
10332
- name,
10333
- encryptVariableSetValue3(encryptionKey, value)
10334
- ])
10335
- )
10336
- })),
10653
+ updates: request.updates.map(
10654
+ (update) => "nativeConnectionId" in update ? update : {
10655
+ id: update.id,
10656
+ expectedCredentialVersion: update.expectedCredentialVersion,
10657
+ expectedServerUrl: update.expectedServerUrl,
10658
+ headersEncrypted: Object.fromEntries(
10659
+ Object.entries(update.headers).map(([name, value]) => [
10660
+ name,
10661
+ encryptVariableSetValue3(encryptionKey, value)
10662
+ ])
10663
+ )
10664
+ }
10665
+ ),
10666
+ resolveNativeConnection: async (tx, server, nativeConnectionId, replacementServerUrl) => {
10667
+ const connections = await listOwnConnectionAccountsForGrant(tx, authorizedGrant);
10668
+ const source = personalConnectionDelegationSourceForGrant(authorizedGrant);
10669
+ try {
10670
+ return nativeSessionConnectionReplacement({
10671
+ accountId: grant.accountId,
10672
+ workspaceId: grant.workspaceId,
10673
+ subjectId: source.kind === "subject" ? source.subjectId : null,
10674
+ serverUrl: server.url,
10675
+ ...replacementServerUrl ? { replacementServerUrl } : {},
10676
+ currentRef: server.connectionRef,
10677
+ nativeConnectionId,
10678
+ connections
10679
+ });
10680
+ } catch {
10681
+ throw new SessionMcpCredentialRotationError("connection_unavailable");
10682
+ }
10683
+ },
10337
10684
  authorize: async (tx) => {
10338
10685
  await externalAuthorize?.(tx);
10339
10686
  const fresh = await reauthorize(tx);
@@ -10356,6 +10703,7 @@ async function rotateSessionMcpCredentialsForRequest(deps, authorization, sessio
10356
10703
  operation: "session.mcp.credentials.rotate",
10357
10704
  surface: "http"
10358
10705
  });
10706
+ authorizedGrant = fresh;
10359
10707
  }
10360
10708
  });
10361
10709
  } catch (error) {
@@ -10366,7 +10714,7 @@ async function rotateSessionMcpCredentialsForRequest(deps, authorization, sessio
10366
10714
  if (error instanceof SessionAuthorizationUnavailableError)
10367
10715
  throw new HTTPException16(503, { message: "credential rotation authorization unavailable" });
10368
10716
  if (error instanceof SessionMcpCredentialRotationError) {
10369
- const status = error.code === "receipt_key_unavailable" ? 503 : error.code === "authority_revoked" ? 403 : error.code === "not_found" ? 404 : error.code === "invalid_request" || error.code === "brokered_server" ? 422 : 409;
10717
+ const status = error.code === "receipt_key_unavailable" ? 503 : error.code === "authority_revoked" ? 403 : error.code === "not_found" ? 404 : error.code === "invalid_request" || error.code === "brokered_server" || error.code === "connection_unavailable" ? 422 : 409;
10370
10718
  throw new HTTPException16(status, { message: `credential_rotation_${error.code}` });
10371
10719
  }
10372
10720
  throw new HTTPException16(503, { message: "credential rotation unavailable" });
@@ -10807,7 +11155,7 @@ function sha256Hex2(bytes) {
10807
11155
  }
10808
11156
 
10809
11157
  // src/domain/skill-search.ts
10810
- import { pinnedFetch, readResponseJsonBounded } from "@opengeni/network";
11158
+ import { pinnedFetch as pinnedFetch2, readResponseJsonBounded } from "@opengeni/network";
10811
11159
  var PublicSkillSearchError = class extends Error {
10812
11160
  constructor(code, message, retryAfterSeconds = null) {
10813
11161
  super(message);
@@ -10822,7 +11170,7 @@ var maxResponseBytes = 256 * 1024;
10822
11170
  var maxResults = 20;
10823
11171
  var ownerPattern = /^[a-z0-9](?:[a-z0-9-]{0,38})$/iu;
10824
11172
  var segmentPattern = /^[a-z0-9](?:[a-z0-9._-]{0,98}[a-z0-9])?$/iu;
10825
- function createPublicSkillSearchClient(settings, fetcher = pinnedFetch) {
11173
+ function createPublicSkillSearchClient(settings, fetcher = pinnedFetch2) {
10826
11174
  return {
10827
11175
  async search(input) {
10828
11176
  const query = input.query.trim();
@@ -10949,7 +11297,7 @@ function parseRetryAfter(value) {
10949
11297
 
10950
11298
  // src/domain/github-skill-source.ts
10951
11299
  import { HTTPException as HTTPException19 } from "hono/http-exception";
10952
- import { pinnedFetch as pinnedFetch2, readResponseJsonBounded as readResponseJsonBounded2, readResponseTextBounded } from "@opengeni/network";
11300
+ import { pinnedFetch as pinnedFetch3, readResponseJsonBounded as readResponseJsonBounded2, readResponseTextBounded } from "@opengeni/network";
10953
11301
  import {
10954
11302
  PORTABLE_SKILL_MAX_FILES as PORTABLE_SKILL_MAX_FILES2,
10955
11303
  PORTABLE_SKILL_MAX_FILE_BYTES as PORTABLE_SKILL_MAX_FILE_BYTES2,
@@ -11050,7 +11398,7 @@ function createGitHubSkillSourceClient(settings, requestJson = (path, maxBytes,
11050
11398
  }
11051
11399
  async function downloadSkillSnapshot(settings, owner, repository, slug) {
11052
11400
  const signal = AbortSignal.timeout(githubRequestTimeoutMs);
11053
- const response = await pinnedFetch2(
11401
+ const response = await pinnedFetch3(
11054
11402
  `https://skills.sh/api/download/${[owner, repository, slug].map(encodeURIComponent).join("/")}`,
11055
11403
  { headers: { accept: "application/json" }, credentials: "omit", redirect: "manual", signal },
11056
11404
  settings,
@@ -11085,7 +11433,7 @@ async function githubJson(settings, path, maxBytes, label) {
11085
11433
  const controller = new AbortController();
11086
11434
  const timeout = setTimeout(() => controller.abort(), githubRequestTimeoutMs);
11087
11435
  try {
11088
- const response = await pinnedFetch2(
11436
+ const response = await pinnedFetch3(
11089
11437
  `${githubApiBase}${path}`,
11090
11438
  {
11091
11439
  method: "GET",
@@ -12544,10 +12892,10 @@ import {
12544
12892
  getRig as getRig4,
12545
12893
  getScheduledTask,
12546
12894
  getScheduledTaskIncludingDeletedForUpdate,
12547
- getScheduledTaskXaiProviderAccountAuthoritySnapshot,
12895
+ getScheduledTaskXaiProviderAccountAuthoritySnapshot as getScheduledTaskXaiProviderAccountAuthoritySnapshot2,
12548
12896
  getSandbox as getSandbox4,
12549
12897
  getSessionTurnXaiProviderAccountAuthoritySnapshot as getSessionTurnXaiProviderAccountAuthoritySnapshot2,
12550
- getSession as getSession3,
12898
+ getSession as getSession4,
12551
12899
  getSessionAuthorityProjection as getSessionAuthorityProjection5,
12552
12900
  withSessionRlsActorContext as withSessionRlsActorContext5,
12553
12901
  nestedPostgresSqlState as nestedPostgresSqlState6,
@@ -12804,7 +13152,7 @@ async function createValidatedScheduledTask(input) {
12804
13152
  );
12805
13153
  }
12806
13154
  async function frozenScheduledTaskCreatorPolicy(input) {
12807
- const session = await getSession3(input.db, input.grant.workspaceId, input.sessionId);
13155
+ const session = await getSession4(input.db, input.grant.workspaceId, input.sessionId);
12808
13156
  if (!session) {
12809
13157
  throw new HTTPException21(403, {
12810
13158
  message: "the calling agent session is not available in this workspace"
@@ -13002,7 +13350,7 @@ async function validateScheduledTaskTarget(input) {
13002
13350
  }
13003
13351
  throw error;
13004
13352
  }
13005
- const session = await getSession3(input.db, input.grant.workspaceId, input.targetSessionId);
13353
+ const session = await getSession4(input.db, input.grant.workspaceId, input.targetSessionId);
13006
13354
  if (!session || session.accountId !== input.grant.accountId) {
13007
13355
  throw new HTTPException21(404, { message: "target session not found" });
13008
13356
  }
@@ -13274,7 +13622,7 @@ async function validatedScheduledTaskUpdate(input) {
13274
13622
  });
13275
13623
  if (beforeUpdateCommit) update.beforeUpdateCommit = beforeUpdateCommit;
13276
13624
  }
13277
- const existingXaiAuthority = await getScheduledTaskXaiProviderAccountAuthoritySnapshot(
13625
+ const existingXaiAuthority = await getScheduledTaskXaiProviderAccountAuthoritySnapshot2(
13278
13626
  input.db,
13279
13627
  input.existing.workspaceId,
13280
13628
  input.existing.id
@@ -13304,22 +13652,32 @@ async function validatedScheduledTaskUpdate(input) {
13304
13652
  rigId: input.payload.rigId !== void 0 ? input.payload.rigId : input.existing.rigId,
13305
13653
  agentConfig: nextAgentConfig
13306
13654
  });
13655
+ const nextConnectionTools = await scheduledConnectionTools(
13656
+ input.db,
13657
+ input.grant.workspaceId,
13658
+ runtimeSettings,
13659
+ nextTarget,
13660
+ nextAgentConfig.tools,
13661
+ ownerSubjectId ?? void 0
13662
+ );
13663
+ const priorMcpIds = new Set(
13664
+ input.existing.agentConfig.tools.filter((tool) => tool.kind === "mcp").map((tool) => tool.id)
13665
+ );
13666
+ const nextMcpIds = new Set(
13667
+ nextConnectionTools.filter((tool) => tool.kind === "mcp").map((tool) => tool.id)
13668
+ );
13669
+ const authoritySelections = (nextAgentConfig.connectionAccounts ?? []).filter(
13670
+ (selection) => input.payload.connectionAccounts !== void 0 || !priorMcpIds.has(selection.serverId) || nextMcpIds.has(selection.serverId)
13671
+ );
13307
13672
  const acceptedConnections = await freezeConnectionAccounts({
13308
13673
  db: input.db,
13309
13674
  accountId: input.grant.accountId,
13310
13675
  workspaceId: input.grant.workspaceId,
13311
13676
  settings: nextTarget ? settingsWithSessionMcpServerMetadata(runtimeSettings, nextTarget.mcpServers) : runtimeSettings,
13312
- tools: await scheduledConnectionTools(
13313
- input.db,
13314
- input.grant.workspaceId,
13315
- runtimeSettings,
13316
- nextTarget,
13317
- nextAgentConfig.tools,
13318
- ownerSubjectId ?? void 0
13319
- ),
13677
+ tools: nextConnectionTools,
13320
13678
  resources: nextTarget?.resources ?? nextAgentConfig.resources,
13321
13679
  source: ownerSubjectId ? { kind: "subject", subjectId: ownerSubjectId, accountId: input.existing.accountId } : { kind: "none" },
13322
- authoritySelections: nextAgentConfig.connectionAccounts ?? [],
13680
+ authoritySelections,
13323
13681
  authoritySelectionsFrozen: input.payload.connectionAccounts === void 0 && input.existing.agentConfig.connectionAccountsFrozen === true,
13324
13682
  ...scheduledConnectionSurfaceEligibility(runtimeSettings, nextTarget)
13325
13683
  });
@@ -13564,7 +13922,7 @@ function manualScheduledTaskTriggerUsageKey(workspaceId, taskId, triggerToken) {
13564
13922
  }
13565
13923
  async function validateScheduledTaskAgentConfig(input) {
13566
13924
  const actor = scheduledTaskInitiatorForGrant(input.grant).actor;
13567
- const parent = actor ? await getSession3(input.db, input.workspaceId, actor.sessionId) : null;
13925
+ const parent = actor ? await getSession4(input.db, input.workspaceId, actor.sessionId) : null;
13568
13926
  if (actor && (!parent || parent.accountId !== input.grant.accountId)) {
13569
13927
  throw new HTTPException21(403, {
13570
13928
  message: "Scheduled Skill selection requires the creating agent's session"
@@ -16109,6 +16467,7 @@ import {
16109
16467
  getSandbox as getSandbox5,
16110
16468
  getVariableSet as getVariableSet3,
16111
16469
  NewSessionDraftAccessError,
16470
+ newSessionDraftModelProvided,
16112
16471
  newSessionDraftSelectedProjectChannelId,
16113
16472
  newSessionDraftToolsProvided,
16114
16473
  newSessionSelectionHistory,
@@ -16119,6 +16478,7 @@ import {
16119
16478
  withWorkspaceSubjectRls as withWorkspaceSubjectRls6
16120
16479
  } from "@opengeni/db";
16121
16480
  import { HTTPException as HTTPException23 } from "hono/http-exception";
16481
+ import { canonicalizeConfiguredModelId as canonicalizeConfiguredModelId3 } from "@opengeni/config";
16122
16482
  function hasOwn(value, key) {
16123
16483
  return typeof value === "object" && value !== null && Object.hasOwn(value, key);
16124
16484
  }
@@ -16134,16 +16494,39 @@ function mapNewSessionDraft(row) {
16134
16494
  model: row.model,
16135
16495
  reasoningEffort: row.reasoningEffort,
16136
16496
  latencyMode: row.latencyMode,
16497
+ ...newSessionDraftModelProvided(row) !== void 0 ? { modelProvided: newSessionDraftModelProvided(row) } : {},
16137
16498
  ...selectedProjectChannelId !== void 0 ? { selectedProjectChannelId } : {},
16138
16499
  options: publicNewSessionDraftOptions(row),
16139
16500
  selectionHistory: newSessionSelectionHistory(row),
16140
16501
  updatedAt: row.updatedAt.toISOString()
16141
16502
  });
16142
16503
  }
16143
- async function hydrateNewSessionDraft(deps, grant, workspaceId, row) {
16504
+ function draftModelProvided(settings, draft) {
16505
+ if (draft.modelProvided !== void 0) return draft.modelProvided;
16506
+ return !(canonicalizeConfiguredModelId3(settings, draft.model) === canonicalizeConfiguredModelId3(settings, settings.openaiModel) && draft.reasoningEffort === settings.openaiReasoningEffort && draft.latencyMode === "standard");
16507
+ }
16508
+ async function actorDefaultModel(deps, grant, workspaceId) {
16509
+ return await resolveDefaultSessionModel(deps.db, deps.settings, {
16510
+ accountId: grant.accountId,
16511
+ workspaceId,
16512
+ subjectId: grant.subjectId
16513
+ });
16514
+ }
16515
+ async function hydrateNewSessionDraft(deps, grant, workspaceId, row, readOptions = {}) {
16144
16516
  if (!row) return null;
16145
- const mapped = mapNewSessionDraft(row);
16146
- if (!mapped) return null;
16517
+ const stored = mapNewSessionDraft(row);
16518
+ if (!stored) return null;
16519
+ const modelProvided = draftModelProvided(deps.settings, stored);
16520
+ let mapped = { ...stored, modelProvided };
16521
+ if (!modelProvided && readOptions.projectDefaultModel !== false) {
16522
+ const resolved = await actorDefaultModel(deps, grant, workspaceId);
16523
+ mapped = {
16524
+ ...mapped,
16525
+ model: resolved.model,
16526
+ reasoningEffort: resolved.reasoningEffort,
16527
+ latencyMode: resolved.model === stored.model ? stored.latencyMode : "standard"
16528
+ };
16529
+ }
16147
16530
  const runtimeSettings = await settingsWithEnabledCapabilityMcpServers(
16148
16531
  deps.db,
16149
16532
  workspaceId,
@@ -16233,7 +16616,7 @@ async function hydrateNewSessionDraft(deps, grant, workspaceId, row) {
16233
16616
  options
16234
16617
  };
16235
16618
  }
16236
- async function getActorNewSessionDraftInFileScope(deps, grant, workspaceId) {
16619
+ async function getActorNewSessionDraftInFileScope(deps, grant, workspaceId, readOptions = {}) {
16237
16620
  const row = await withWorkspaceSubjectRls6(
16238
16621
  deps.db,
16239
16622
  workspaceId,
@@ -16243,15 +16626,19 @@ async function getActorNewSessionDraftInFileScope(deps, grant, workspaceId) {
16243
16626
  subjectId: grant.subjectId
16244
16627
  })
16245
16628
  );
16246
- return await hydrateNewSessionDraft(deps, grant, workspaceId, row) ?? {
16629
+ const hydrated = await hydrateNewSessionDraft(deps, grant, workspaceId, row, readOptions);
16630
+ if (hydrated) return hydrated;
16631
+ const resolved = readOptions.projectDefaultModel === false ? { model: deps.settings.openaiModel, reasoningEffort: deps.settings.openaiReasoningEffort } : await actorDefaultModel(deps, grant, workspaceId);
16632
+ return {
16247
16633
  revision: 0,
16248
16634
  text: "",
16249
16635
  resources: [],
16250
16636
  tools: [],
16251
16637
  toolsProvided: false,
16252
- model: deps.settings.openaiModel,
16253
- reasoningEffort: deps.settings.openaiReasoningEffort,
16638
+ model: resolved.model,
16639
+ reasoningEffort: resolved.reasoningEffort,
16254
16640
  latencyMode: "standard",
16641
+ modelProvided: false,
16255
16642
  options: {},
16256
16643
  selectionHistory: { projects: [] },
16257
16644
  updatedAt: null
@@ -16302,6 +16689,7 @@ async function saveActorNewSessionDraftInFileScope(deps, grant, workspaceId, raw
16302
16689
  model: input.model,
16303
16690
  reasoningEffort: input.reasoningEffort,
16304
16691
  latencyMode: input.latencyMode,
16692
+ ...input.modelProvided !== void 0 ? { modelProvided: input.modelProvided } : {},
16305
16693
  ...input.selectedProjectChannelId !== void 0 ? { selectedProjectChannelId: input.selectedProjectChannelId } : {},
16306
16694
  options: input.options,
16307
16695
  // Only managed people are removed through removeWorkspaceMember().
@@ -16317,7 +16705,8 @@ async function saveActorNewSessionDraftInFileScope(deps, grant, workspaceId, raw
16317
16705
  })
16318
16706
  )
16319
16707
  );
16320
- return mapNewSessionDraft(saved);
16708
+ const mapped = mapNewSessionDraft(saved);
16709
+ return { ...mapped, modelProvided: draftModelProvided(deps.settings, mapped) };
16321
16710
  } catch (error) {
16322
16711
  if (error instanceof NewSessionDraftAccessError) {
16323
16712
  throw new HTTPException23(403, { message: error.message });
@@ -16325,11 +16714,11 @@ async function saveActorNewSessionDraftInFileScope(deps, grant, workspaceId, raw
16325
16714
  throw error;
16326
16715
  }
16327
16716
  }
16328
- async function getActorNewSessionDraft(deps, grant, workspaceId, authorization) {
16717
+ async function getActorNewSessionDraft(deps, grant, workspaceId, authorization, readOptions = {}) {
16329
16718
  const actor = authorization ? await fileOwnerContextForAccess(deps, authorization, "sessions:read") : { subjectId: grant.subjectId, privateFileOwnerSubjectId: null };
16330
16719
  return withSessionRlsActorContext6(
16331
16720
  actor,
16332
- () => getActorNewSessionDraftInFileScope(deps, grant, workspaceId)
16721
+ () => getActorNewSessionDraftInFileScope(deps, grant, workspaceId, readOptions)
16333
16722
  );
16334
16723
  }
16335
16724
  async function saveActorNewSessionDraft(...args) {
@@ -16338,11 +16727,15 @@ async function saveActorNewSessionDraft(...args) {
16338
16727
  return withSessionRlsActorContext6(actor, () => saveActorNewSessionDraftInFileScope(...args));
16339
16728
  }
16340
16729
  async function getActorNewSessionDefaults(deps, grant, workspaceId) {
16341
- const draft = await getActorNewSessionDraft(deps, grant, workspaceId);
16730
+ const draft = await getActorNewSessionDraft(deps, grant, workspaceId, void 0, {
16731
+ projectDefaultModel: false
16732
+ });
16342
16733
  const options = draft.options;
16343
16734
  return {
16344
- // Revision zero is a synthetic empty form, not a user's model preference.
16345
- ...draft.revision > 0 ? {
16735
+ // Only a model the person chose is carried over. A draft that follows the
16736
+ // default (including the synthetic revision-zero form) leaves the model
16737
+ // out, so session creation resolves the same default itself.
16738
+ ...draft.revision > 0 && draft.modelProvided === true ? {
16346
16739
  model: draft.model,
16347
16740
  reasoningEffort: draft.reasoningEffort,
16348
16741
  latencyMode: draft.latencyMode
@@ -16405,7 +16798,7 @@ import {
16405
16798
  deleteSessionQueueItemInTransaction,
16406
16799
  editQueuedTurnInTransaction,
16407
16800
  getComposerDraftInTransaction,
16408
- getSession as getSession4,
16801
+ getSession as getSession5,
16409
16802
  getSessionEvent as getSessionEvent3,
16410
16803
  getWorkspaceControlEvent as getWorkspaceControlEvent2,
16411
16804
  getSessionQueueSnapshot,
@@ -17103,7 +17496,7 @@ async function getHumanComposerDraft(deps, context) {
17103
17496
  );
17104
17497
  const mapped = composerDraft(row);
17105
17498
  if (mapped) return mapped;
17106
- const session = await getSession4(deps.db, context.workspaceId, context.sessionId);
17499
+ const session = await getSession5(deps.db, context.workspaceId, context.sessionId);
17107
17500
  if (!session) throw new Error(`Session not found: ${context.sessionId}`);
17108
17501
  return {
17109
17502
  revision: 0,
@@ -18044,6 +18437,7 @@ export {
18044
18437
  causalFrontierDominates,
18045
18438
  causalFrontiersEqual,
18046
18439
  checkLimit,
18440
+ clampReasoningEffortForConfiguredModel,
18047
18441
  classifyRigVerificationOutcome,
18048
18442
  codexAppsCatalogItem,
18049
18443
  compareCodeUnits,
@@ -18069,10 +18463,12 @@ export {
18069
18463
  createSessionForRequestWithOutcome,
18070
18464
  createValidatedScheduledTask,
18071
18465
  creationInitiatorForGrant,
18466
+ creditsDefaultSessionModel,
18072
18467
  decodeEditableArtifactBrokerHint,
18073
18468
  decodeEditableArtifactLiveClientWireFrame,
18074
18469
  decodeEditableArtifactLiveServerWireFrame,
18075
18470
  defaultPrReviewProviderBaseUrl,
18471
+ defaultReasoningEffortForConfiguredModel,
18076
18472
  defaultSessionMcpServerIds,
18077
18473
  defaultVideoGenerationPolicy,
18078
18474
  deleteHumanQueuePrompt,
@@ -18083,6 +18479,7 @@ export {
18083
18479
  disableCapability,
18084
18480
  discoverMcpRegistryCapabilities,
18085
18481
  documentEmbeddingCostMicros,
18482
+ draftModelProvided,
18086
18483
  editHumanQueuePrompt,
18087
18484
  editableArtifactActorKey,
18088
18485
  editableArtifactAuthorizationRevisionPortFromPostgres,
@@ -18187,6 +18584,7 @@ export {
18187
18584
  listRigVersionsForApi,
18188
18585
  listSkills,
18189
18586
  loadRigDefaultVariableSetEnvironment,
18587
+ loadWorkspaceModelSelectionInput,
18190
18588
  lockActiveCustomModelForAdmission,
18191
18589
  lookupExternalIdentityForRequest,
18192
18590
  managedSessionGroupBackend,
@@ -18305,12 +18703,16 @@ export {
18305
18703
  resolveCatalogSettings,
18306
18704
  resolveChildGoalFromAcceptedSnapshot,
18307
18705
  resolveCodexAppsCredentialIdForRun,
18706
+ resolveDefaultSessionModel,
18707
+ resolveDefaultSessionModelForSelections,
18308
18708
  resolveFikenDefaultCompanySlug,
18309
18709
  resolveFirstPartyMcpToolsForCreate,
18310
18710
  resolveGitHubRepositoryBindings,
18311
18711
  resolveMemberSubjectId,
18312
18712
  resolveRigProviderImageForRun,
18313
18713
  resolveRigProviderImageSelection,
18714
+ resolveScheduledTaskDefaultModel,
18715
+ resolveScheduledTaskPreflightModel,
18314
18716
  resolveSessionCreateScope,
18315
18717
  resolveSessionCreateVisibility,
18316
18718
  resolveSessionSandboxRuntime,
@@ -18351,6 +18753,7 @@ export {
18351
18753
  scheduledTaskTriggerToken,
18352
18754
  searchCapabilityCatalogItems,
18353
18755
  searchKnowledgeEntries,
18756
+ selectDefaultSessionModel,
18354
18757
  selectedPersonalConnectionServers,
18355
18758
  sendAgentSessionMessage,
18356
18759
  sessionGroupMachinePresentation,