@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/application/new-session-drafts.d.ts +21 -5
- package/dist/default-session-model.d.ts +110 -0
- package/dist/domain/capabilities.d.ts +2 -1
- package/dist/domain/pr-review.d.ts +2 -2
- package/dist/domain/session-native-connection-replacement.d.ts +14 -0
- package/dist/domain/sessions.d.ts +9 -6
- package/dist/index.d.ts +1 -0
- package/dist/index.js +493 -90
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
- package/src/application/new-session-drafts.ts +101 -22
- package/src/application/session-mcp-credential-rotation.ts +57 -15
- package/src/default-session-model.ts +467 -0
- package/src/domain/capabilities.ts +17 -1
- package/src/domain/personal-connection-delegations.ts +20 -17
- package/src/domain/scheduled-tasks.ts +25 -9
- package/src/domain/session-native-connection-replacement.ts +64 -0
- package/src/domain/sessions.ts +42 -7
- package/src/index.ts +1 -0
- package/src/session-authorization.ts +17 -16
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
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
|
236
|
-
|
|
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
|
|
361
|
-
|
|
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
|
|
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(
|
|
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 =
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
return connections
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
10306
|
-
|
|
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(
|
|
10329
|
-
|
|
10330
|
-
|
|
10331
|
-
|
|
10332
|
-
|
|
10333
|
-
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
16146
|
-
if (!
|
|
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
|
-
|
|
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:
|
|
16253
|
-
reasoningEffort:
|
|
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
|
-
|
|
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
|
-
//
|
|
16345
|
-
|
|
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
|
|
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
|
|
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,
|