@opengeni/core 0.16.3 → 0.17.1
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/domain/personal-connection-delegations.d.ts +48 -0
- package/dist/domain/scheduled-tasks.d.ts +8 -3
- package/dist/domain/sessions.d.ts +11 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +240 -1
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
- package/src/domain/personal-connection-delegations.ts +247 -0
- package/src/domain/scheduled-tasks.ts +79 -3
- package/src/domain/sessions.ts +29 -2
- package/src/index.ts +1 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { McpServerConfig, Settings } from "@opengeni/config";
|
|
2
|
+
import type { AccessGrant, ConnectionMetadata, McpPersonalConnectionDelegation, SessionTurn, ToolRef } from "@opengeni/contracts";
|
|
3
|
+
import { type Database, type ResolveConnectionCredentialInput, type ResolveConnectionCredentialResult } from "@opengeni/db";
|
|
4
|
+
export type PersonalConnectionDelegationSource = {
|
|
5
|
+
kind: "subject";
|
|
6
|
+
subjectId: string;
|
|
7
|
+
} | {
|
|
8
|
+
kind: "turn";
|
|
9
|
+
sessionId: string;
|
|
10
|
+
turnId: string;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "none";
|
|
13
|
+
};
|
|
14
|
+
export declare function directPersonalConnectionSubjectId(turn: Pick<SessionTurn, "source" | "initiator" | "initiatorContext">): string | undefined;
|
|
15
|
+
export declare function personalConnectionDelegationSourceForGrant(grant: AccessGrant): PersonalConnectionDelegationSource;
|
|
16
|
+
export declare function selectedPersonalConnectionServers(settings: Pick<Settings, "mcpServers">, tools: ToolRef[]): McpServerConfig[];
|
|
17
|
+
export declare function personalConnectionDelegationsFromVisibleConnections(input: {
|
|
18
|
+
servers: McpServerConfig[];
|
|
19
|
+
subjectId: string;
|
|
20
|
+
connections: ConnectionMetadata[];
|
|
21
|
+
}): McpPersonalConnectionDelegation[];
|
|
22
|
+
export declare function personalConnectionDelegationsFromParent(input: {
|
|
23
|
+
servers: McpServerConfig[];
|
|
24
|
+
parentDelegations: McpPersonalConnectionDelegation[];
|
|
25
|
+
}): McpPersonalConnectionDelegation[];
|
|
26
|
+
export declare function personalConnectionDelegationsEqual(left: McpPersonalConnectionDelegation[], right: McpPersonalConnectionDelegation[]): boolean;
|
|
27
|
+
export declare function personalConnectionDelegationForServer(delegations: McpPersonalConnectionDelegation[], server: Pick<McpServerConfig, "id" | "connectionRef">): McpPersonalConnectionDelegation | null;
|
|
28
|
+
type ConnectionCredentialResolver = (request: ResolveConnectionCredentialInput) => Promise<ResolveConnectionCredentialResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Resolves subject-owned MCP credentials only through the exact authority
|
|
31
|
+
* frozen on the causal turn. A direct human subject, worker Toolspace caller,
|
|
32
|
+
* retry, or recovery can identify the caller, but none may widen or replace
|
|
33
|
+
* the persisted connection UUID.
|
|
34
|
+
*/
|
|
35
|
+
export declare function withFrozenPersonalConnectionDelegations(input: {
|
|
36
|
+
resolveCredential: ConnectionCredentialResolver;
|
|
37
|
+
settings: Pick<Settings, "mcpServers">;
|
|
38
|
+
personalConnectionDelegations: McpPersonalConnectionDelegation[];
|
|
39
|
+
ownerHasWorkspaceMembership: (subjectId: string) => Promise<boolean>;
|
|
40
|
+
}): ConnectionCredentialResolver;
|
|
41
|
+
export declare function freezePersonalConnectionDelegations(input: {
|
|
42
|
+
db: Database;
|
|
43
|
+
workspaceId: string;
|
|
44
|
+
settings: Pick<Settings, "mcpServers">;
|
|
45
|
+
tools: ToolRef[];
|
|
46
|
+
source: PersonalConnectionDelegationSource;
|
|
47
|
+
}): Promise<McpPersonalConnectionDelegation[]>;
|
|
48
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Settings } from "@opengeni/config";
|
|
2
|
-
import type { AccessGrant, ScheduledTask, CreateScheduledTaskRequest as CreateScheduledTaskPayload, UpdateScheduledTaskRequest as UpdateScheduledTaskPayload } from "@opengeni/contracts";
|
|
2
|
+
import type { AccessGrant, McpPersonalConnectionDelegation, ScheduledTask, CreateScheduledTaskRequest as CreateScheduledTaskPayload, UpdateScheduledTaskRequest as UpdateScheduledTaskPayload } from "@opengeni/contracts";
|
|
3
3
|
import { type Database, type UpdateScheduledTaskInput } from "@opengeni/db";
|
|
4
4
|
import type { SessionWorkflowClient } from "../dependencies";
|
|
5
5
|
import type { ObjectStorageDependency } from "../dependencies";
|
|
@@ -32,7 +32,12 @@ export declare function validatedScheduledTaskUpdate(input: {
|
|
|
32
32
|
toolsProvided?: boolean;
|
|
33
33
|
}): Promise<UpdateScheduledTaskInput>;
|
|
34
34
|
export declare function requireScheduledTaskForApi(db: Database, workspaceId: string, taskId: string): Promise<ScheduledTask>;
|
|
35
|
-
export
|
|
35
|
+
export type ScheduledTaskRestoreState = {
|
|
36
|
+
task: ScheduledTask;
|
|
37
|
+
personalConnectionDelegations: McpPersonalConnectionDelegation[];
|
|
38
|
+
};
|
|
39
|
+
export declare function captureScheduledTaskRestoreState(db: Database, task: ScheduledTask): Promise<ScheduledTaskRestoreState>;
|
|
40
|
+
export declare function restoreScheduledTask(db: Database, previous: ScheduledTaskRestoreState): Promise<ScheduledTask>;
|
|
36
41
|
export declare function syncCreatedScheduledTask(input: {
|
|
37
42
|
db: Database;
|
|
38
43
|
workflowClient: SessionWorkflowClient;
|
|
@@ -41,7 +46,7 @@ export declare function syncCreatedScheduledTask(input: {
|
|
|
41
46
|
export declare function syncUpdatedScheduledTask(input: {
|
|
42
47
|
db: Database;
|
|
43
48
|
workflowClient: SessionWorkflowClient;
|
|
44
|
-
previous:
|
|
49
|
+
previous: ScheduledTaskRestoreState;
|
|
45
50
|
task: ScheduledTask;
|
|
46
51
|
}): Promise<void>;
|
|
47
52
|
export declare function scheduledTaskTemporalScheduleId(taskId: string): string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Settings } from "@opengeni/config";
|
|
2
|
-
import { SessionSpawnDenial, type AccessGrant, type CreateSessionResponse, type GoalSpec, type FirstPartyMcpToolName, type Permission, type ReasoningEffort, type ResourceRef, type Session, type SessionSkill, type SessionEvent, SessionMcpApprovalPolicy, type SessionMcpCredentialUpdateInput, type SessionMcpServerMetadata, type UpdateSessionMcpApprovalPolicyResponse, type UpdateSessionToolPolicyRequest, type SessionAuthorizationPort, type SessionToolPolicy, type SessionTurn, type ToolRef, type TurnInitiator, type TurnInitiatorContext, type TurnExecutionPolicyV1 } from "@opengeni/contracts";
|
|
2
|
+
import { SessionSpawnDenial, type AccessGrant, type CreateSessionResponse, type GoalSpec, type FirstPartyMcpToolName, type McpPersonalConnectionDelegation, type Permission, type ReasoningEffort, type ResourceRef, type Session, type SessionSkill, type SessionEvent, SessionMcpApprovalPolicy, type SessionMcpCredentialUpdateInput, type SessionMcpServerMetadata, type UpdateSessionMcpApprovalPolicyResponse, type UpdateSessionToolPolicyRequest, type SessionAuthorizationPort, type SessionToolPolicy, type SessionTurn, type ToolRef, type TurnInitiator, type TurnInitiatorContext, type TurnExecutionPolicyV1 } from "@opengeni/contracts";
|
|
3
3
|
import { type CreateSessionMcpServerInput, type Database, type UpdateSessionMcpServerCredentialsInput, type SessionCommandActor } from "@opengeni/db";
|
|
4
4
|
import { type EventBus } from "@opengeni/events";
|
|
5
5
|
import type { AcceptSessionUserMessageDependencies, ApiRouteDeps, SessionWorkflowClient } from "../dependencies";
|
|
@@ -40,6 +40,14 @@ export declare function sessionSpawnDenialEnvelope(error: SessionSpawnDeniedErro
|
|
|
40
40
|
};
|
|
41
41
|
};
|
|
42
42
|
};
|
|
43
|
+
export type FrozenCreationInitiator = {
|
|
44
|
+
initiator?: TurnInitiator;
|
|
45
|
+
context?: TurnInitiatorContext;
|
|
46
|
+
actor?: Extract<SessionCommandActor, {
|
|
47
|
+
type: "agent_attempt";
|
|
48
|
+
}>;
|
|
49
|
+
};
|
|
50
|
+
export declare function creationInitiatorForGrant(grant: AccessGrant): FrozenCreationInitiator;
|
|
43
51
|
export declare function settingsWithSessionMcpServerMetadata(settings: Settings, servers: SessionMcpServerMetadata[]): Settings;
|
|
44
52
|
export declare function createAndStartSession(input: {
|
|
45
53
|
requestedSessionId?: string;
|
|
@@ -79,6 +87,7 @@ export declare function createAndStartSession(input: {
|
|
|
79
87
|
firstPartyMcpTools: FirstPartyMcpToolName[];
|
|
80
88
|
mcpServers?: CreateSessionMcpServerInput[];
|
|
81
89
|
sessionMcpServers?: SessionMcpServerMetadata[];
|
|
90
|
+
personalConnectionDelegations?: McpPersonalConnectionDelegation[];
|
|
82
91
|
parentSessionId?: string | null;
|
|
83
92
|
createIdempotencyKey?: string | null;
|
|
84
93
|
sandboxGroupId?: string | null;
|
|
@@ -165,6 +174,7 @@ export declare function postUserMessageTurn(input: {
|
|
|
165
174
|
latencyMode?: "standard" | "priority" | "fast" | null;
|
|
166
175
|
clientEventId?: string;
|
|
167
176
|
mcpCredentialUpdates?: UpdateSessionMcpServerCredentialsInput[];
|
|
177
|
+
personalConnectionDelegations?: McpPersonalConnectionDelegation[];
|
|
168
178
|
delivery?: "send" | "steer";
|
|
169
179
|
origin?: "human" | "operator";
|
|
170
180
|
actor?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export * from "./domain/capabilities";
|
|
|
12
12
|
export * from "./domain/environments";
|
|
13
13
|
export * from "./rigs";
|
|
14
14
|
export * from "./domain/packs";
|
|
15
|
+
export * from "./domain/personal-connection-delegations";
|
|
15
16
|
export * from "./domain/resources";
|
|
16
17
|
export * from "./domain/session-tool-policy";
|
|
17
18
|
export * from "./domain/scheduled-tasks";
|
package/dist/index.js
CHANGED
|
@@ -3151,6 +3151,158 @@ async function listRigChangesForApi(deps, workspaceId, rigId, limit) {
|
|
|
3151
3151
|
return await listRigChanges(deps.db, workspaceId, rigId, limit);
|
|
3152
3152
|
}
|
|
3153
3153
|
|
|
3154
|
+
// src/domain/personal-connection-delegations.ts
|
|
3155
|
+
import {
|
|
3156
|
+
getSessionTurnPersonalConnectionDelegations,
|
|
3157
|
+
getWorkspaceGrant as getWorkspaceGrant2,
|
|
3158
|
+
listConnectionsMetadata as listConnectionsMetadata2
|
|
3159
|
+
} from "@opengeni/db";
|
|
3160
|
+
function directPersonalConnectionSubjectId(turn) {
|
|
3161
|
+
if (turn.source !== "user" && turn.source !== "api" || turn.initiator.kind !== "subject") {
|
|
3162
|
+
return void 0;
|
|
3163
|
+
}
|
|
3164
|
+
return ["via", "viaTruncated", "provenanceError", "backfill"].some(
|
|
3165
|
+
(key) => Object.prototype.hasOwnProperty.call(turn.initiatorContext, key)
|
|
3166
|
+
) ? void 0 : turn.initiator.subjectId;
|
|
3167
|
+
}
|
|
3168
|
+
function personalConnectionDelegationSourceForGrant(grant) {
|
|
3169
|
+
const callerSessionId = grant.metadata?.["sessionId"];
|
|
3170
|
+
const callerTurnId = grant.metadata?.["turnId"];
|
|
3171
|
+
if (typeof callerSessionId === "string" && typeof callerTurnId === "string") {
|
|
3172
|
+
return { kind: "turn", sessionId: callerSessionId, turnId: callerTurnId };
|
|
3173
|
+
}
|
|
3174
|
+
if (grant.principalKind === "agent_attempt" || grant.principalKind === "service" || grant.serviceInitiator) {
|
|
3175
|
+
return { kind: "none" };
|
|
3176
|
+
}
|
|
3177
|
+
return { kind: "subject", subjectId: grant.subjectId };
|
|
3178
|
+
}
|
|
3179
|
+
function selectedPersonalConnectionServers(settings, tools) {
|
|
3180
|
+
const selected = new Set(tools.map((tool) => tool.id));
|
|
3181
|
+
return settings.mcpServers.filter(
|
|
3182
|
+
(server) => selected.has(server.id) && server.connectionRef?.subjectScope === "subject"
|
|
3183
|
+
);
|
|
3184
|
+
}
|
|
3185
|
+
function canonicalPersonalConnections(connections) {
|
|
3186
|
+
return [...connections].sort((left, right) => {
|
|
3187
|
+
const active = Number(right.status === "active") - Number(left.status === "active");
|
|
3188
|
+
if (active !== 0) return active;
|
|
3189
|
+
const updated = Date.parse(right.updatedAt) - Date.parse(left.updatedAt);
|
|
3190
|
+
if (updated !== 0) return updated;
|
|
3191
|
+
const created = Date.parse(right.createdAt) - Date.parse(left.createdAt);
|
|
3192
|
+
if (created !== 0) return created;
|
|
3193
|
+
return right.id.localeCompare(left.id);
|
|
3194
|
+
});
|
|
3195
|
+
}
|
|
3196
|
+
function sameProviderDomain(left, right) {
|
|
3197
|
+
return left.toLowerCase() === right.toLowerCase();
|
|
3198
|
+
}
|
|
3199
|
+
function personalConnectionDelegationsFromVisibleConnections(input) {
|
|
3200
|
+
const delegations = [];
|
|
3201
|
+
const connections = canonicalPersonalConnections(input.connections);
|
|
3202
|
+
for (const server of input.servers) {
|
|
3203
|
+
const ref = server.connectionRef;
|
|
3204
|
+
if (!ref || ref.subjectScope !== "subject") continue;
|
|
3205
|
+
const connection = connections.find(
|
|
3206
|
+
(candidate) => candidate.subjectId === input.subjectId && candidate.status === "active" && sameProviderDomain(candidate.providerDomain, ref.providerDomain) && (!ref.kind || candidate.kind === ref.kind) && (!ref.connectionId || candidate.id === ref.connectionId)
|
|
3207
|
+
);
|
|
3208
|
+
if (!connection) continue;
|
|
3209
|
+
delegations.push({
|
|
3210
|
+
serverId: server.id,
|
|
3211
|
+
connectionId: connection.id,
|
|
3212
|
+
ownerSubjectId: input.subjectId,
|
|
3213
|
+
providerDomain: connection.providerDomain,
|
|
3214
|
+
kind: connection.kind
|
|
3215
|
+
});
|
|
3216
|
+
}
|
|
3217
|
+
return delegations;
|
|
3218
|
+
}
|
|
3219
|
+
function personalConnectionDelegationsFromParent(input) {
|
|
3220
|
+
return input.servers.flatMap((server) => {
|
|
3221
|
+
const ref = server.connectionRef;
|
|
3222
|
+
if (!ref || ref.subjectScope !== "subject") return [];
|
|
3223
|
+
const delegation = input.parentDelegations.find(
|
|
3224
|
+
(candidate) => candidate.serverId === server.id && sameProviderDomain(candidate.providerDomain, ref.providerDomain) && (!ref.kind || !candidate.kind || candidate.kind === ref.kind)
|
|
3225
|
+
);
|
|
3226
|
+
return delegation ? [{ ...delegation }] : [];
|
|
3227
|
+
});
|
|
3228
|
+
}
|
|
3229
|
+
function personalConnectionDelegationsEqual(left, right) {
|
|
3230
|
+
if (left.length !== right.length) return false;
|
|
3231
|
+
const byServer = new Map(right.map((delegation) => [delegation.serverId, delegation]));
|
|
3232
|
+
return left.every((delegation) => {
|
|
3233
|
+
const other = byServer.get(delegation.serverId);
|
|
3234
|
+
return other?.connectionId === delegation.connectionId && other.ownerSubjectId === delegation.ownerSubjectId && sameProviderDomain(other.providerDomain, delegation.providerDomain) && other.kind === delegation.kind;
|
|
3235
|
+
});
|
|
3236
|
+
}
|
|
3237
|
+
function personalConnectionDelegationForServer(delegations, server) {
|
|
3238
|
+
const ref = server.connectionRef;
|
|
3239
|
+
if (!ref || ref.subjectScope !== "subject") return null;
|
|
3240
|
+
return delegations.find(
|
|
3241
|
+
(delegation) => delegation.serverId === server.id && sameProviderDomain(delegation.providerDomain, ref.providerDomain) && (!ref.kind || !delegation.kind || delegation.kind === ref.kind)
|
|
3242
|
+
) ?? null;
|
|
3243
|
+
}
|
|
3244
|
+
function personalAuthorityUnavailable(request) {
|
|
3245
|
+
const ref = request.connectionRef;
|
|
3246
|
+
return {
|
|
3247
|
+
status: "auth_needed",
|
|
3248
|
+
reason: "personal_authority_unavailable",
|
|
3249
|
+
providerDomain: ref.providerDomain,
|
|
3250
|
+
...ref.provider ? { provider: ref.provider } : {},
|
|
3251
|
+
...ref.scopes ? { scopes: ref.scopes } : {},
|
|
3252
|
+
...ref.resource ? { resource: ref.resource } : {},
|
|
3253
|
+
...ref.selectedResources ? { selectedResources: ref.selectedResources } : {}
|
|
3254
|
+
};
|
|
3255
|
+
}
|
|
3256
|
+
function withFrozenPersonalConnectionDelegations(input) {
|
|
3257
|
+
return async (request) => {
|
|
3258
|
+
let effectiveRequest = request;
|
|
3259
|
+
if (request.connectionRef.subjectScope === "subject") {
|
|
3260
|
+
const config = input.settings.mcpServers.find((server) => server.id === request.serverId);
|
|
3261
|
+
const delegation = config ? personalConnectionDelegationForServer(input.personalConnectionDelegations, config) : null;
|
|
3262
|
+
if (!delegation || !await input.ownerHasWorkspaceMembership(delegation.ownerSubjectId)) {
|
|
3263
|
+
return personalAuthorityUnavailable(request);
|
|
3264
|
+
}
|
|
3265
|
+
effectiveRequest = {
|
|
3266
|
+
...request,
|
|
3267
|
+
subjectId: delegation.ownerSubjectId,
|
|
3268
|
+
connectionRef: {
|
|
3269
|
+
...request.connectionRef,
|
|
3270
|
+
providerDomain: delegation.providerDomain,
|
|
3271
|
+
connectionId: delegation.connectionId,
|
|
3272
|
+
...delegation.kind ? { kind: delegation.kind } : {}
|
|
3273
|
+
}
|
|
3274
|
+
};
|
|
3275
|
+
}
|
|
3276
|
+
const result = await input.resolveCredential(effectiveRequest);
|
|
3277
|
+
if (result.status === "ok" || request.connectionRef.subjectScope !== "subject") {
|
|
3278
|
+
return result;
|
|
3279
|
+
}
|
|
3280
|
+
return personalAuthorityUnavailable(request);
|
|
3281
|
+
};
|
|
3282
|
+
}
|
|
3283
|
+
async function freezePersonalConnectionDelegations(input) {
|
|
3284
|
+
const servers = selectedPersonalConnectionServers(input.settings, input.tools);
|
|
3285
|
+
if (servers.length === 0 || input.source.kind === "none") return [];
|
|
3286
|
+
if (input.source.kind === "turn") {
|
|
3287
|
+
return personalConnectionDelegationsFromParent({
|
|
3288
|
+
servers,
|
|
3289
|
+
parentDelegations: await getSessionTurnPersonalConnectionDelegations(
|
|
3290
|
+
input.db,
|
|
3291
|
+
input.workspaceId,
|
|
3292
|
+
input.source.sessionId,
|
|
3293
|
+
input.source.turnId
|
|
3294
|
+
)
|
|
3295
|
+
});
|
|
3296
|
+
}
|
|
3297
|
+
const membership = await getWorkspaceGrant2(input.db, input.source.subjectId, input.workspaceId);
|
|
3298
|
+
if (!membership) return [];
|
|
3299
|
+
return personalConnectionDelegationsFromVisibleConnections({
|
|
3300
|
+
servers,
|
|
3301
|
+
subjectId: input.source.subjectId,
|
|
3302
|
+
connections: await listConnectionsMetadata2(input.db, input.workspaceId, input.source.subjectId)
|
|
3303
|
+
});
|
|
3304
|
+
}
|
|
3305
|
+
|
|
3154
3306
|
// src/domain/resources.ts
|
|
3155
3307
|
import {
|
|
3156
3308
|
gitCredentialBindingIdForRepository,
|
|
@@ -3552,6 +3704,7 @@ import {
|
|
|
3552
3704
|
getNestedAgentDepthDeploymentPolicy,
|
|
3553
3705
|
getRig as getRig3,
|
|
3554
3706
|
getScheduledTask,
|
|
3707
|
+
getScheduledTaskPersonalConnectionDelegations,
|
|
3555
3708
|
requireWorkspace as requireWorkspace2,
|
|
3556
3709
|
updateScheduledTask
|
|
3557
3710
|
} from "@opengeni/db";
|
|
@@ -4009,6 +4162,7 @@ async function createAndStartSession(input) {
|
|
|
4009
4162
|
sandboxGroupId: input.sandboxGroupId ?? null,
|
|
4010
4163
|
...input.sandboxOs ? { sandboxOs: input.sandboxOs } : {},
|
|
4011
4164
|
mcpServers: input.mcpServers ?? [],
|
|
4165
|
+
personalConnectionDelegations: input.personalConnectionDelegations ?? [],
|
|
4012
4166
|
maxNestedAgentDepthOverride: input.maxNestedAgentDepthOverride ?? null,
|
|
4013
4167
|
allowNestedAgentDepthIncrease: input.allowNestedAgentDepthIncrease ?? false,
|
|
4014
4168
|
subjectId: input.subjectId ?? null
|
|
@@ -4053,6 +4207,7 @@ async function createAndStartSession(input) {
|
|
|
4053
4207
|
sandboxGroupId: input.sandboxGroupId ?? null,
|
|
4054
4208
|
...input.sandboxOs ? { sandboxOs: input.sandboxOs } : {},
|
|
4055
4209
|
mcpServers: input.mcpServers ?? [],
|
|
4210
|
+
personalConnectionDelegations: input.personalConnectionDelegations ?? [],
|
|
4056
4211
|
maxNestedAgentDepthOverride: input.maxNestedAgentDepthOverride ?? null,
|
|
4057
4212
|
allowNestedAgentDepthIncrease: input.allowNestedAgentDepthIncrease ?? false,
|
|
4058
4213
|
subjectId: input.subjectId ?? null
|
|
@@ -4251,6 +4406,7 @@ async function postUserMessageTurn(input) {
|
|
|
4251
4406
|
reasoningEffortFallback: input.reasoningEffortFallback ?? settings.openaiReasoningEffort,
|
|
4252
4407
|
turnExecutionPolicy: input.turnExecutionPolicy,
|
|
4253
4408
|
source: input.origin === "operator" ? "api" : "user",
|
|
4409
|
+
personalConnectionDelegations: input.personalConnectionDelegations ?? [],
|
|
4254
4410
|
mcpCredentialUpdates: input.mcpCredentialUpdates ?? []
|
|
4255
4411
|
})
|
|
4256
4412
|
)
|
|
@@ -4405,6 +4561,13 @@ async function createSessionForRequest(deps, grant, workspaceId, rawPayload) {
|
|
|
4405
4561
|
toolPolicy = { mode: "workspace_default", inheritedFromSessionId: null };
|
|
4406
4562
|
}
|
|
4407
4563
|
const tools = withFirstPartyTools(selectedTools, runtimeSettings);
|
|
4564
|
+
const personalConnectionDelegations = await freezePersonalConnectionDelegations({
|
|
4565
|
+
db,
|
|
4566
|
+
workspaceId,
|
|
4567
|
+
settings: runtimeSettings,
|
|
4568
|
+
tools,
|
|
4569
|
+
source: personalConnectionDelegationSourceForGrant(grant)
|
|
4570
|
+
});
|
|
4408
4571
|
await validateGitHubRepositorySelection(db, workspaceId, resources);
|
|
4409
4572
|
if (resources.some((resource) => resource.kind === "file") && !objectStorage) {
|
|
4410
4573
|
throw new HTTPException10(503, { message: "object storage is not configured" });
|
|
@@ -4640,6 +4803,7 @@ async function createSessionForRequest(deps, grant, workspaceId, rawPayload) {
|
|
|
4640
4803
|
firstPartyMcpTools,
|
|
4641
4804
|
mcpServers: sessionMcpServers.dbServers,
|
|
4642
4805
|
sessionMcpServers: sessionMcpServers.metadata,
|
|
4806
|
+
personalConnectionDelegations,
|
|
4643
4807
|
parentSessionId,
|
|
4644
4808
|
createIdempotencyKey: payload.idempotencyKey ?? null,
|
|
4645
4809
|
maxNestedAgentDepthOverride: payload.maxNestedAgentDepth ?? null,
|
|
@@ -4742,6 +4906,14 @@ async function acceptSessionUserMessage(deps, grant, workspaceId, sessionId, inp
|
|
|
4742
4906
|
session: existingSession,
|
|
4743
4907
|
updates: input.mcpCredentialUpdates ?? []
|
|
4744
4908
|
});
|
|
4909
|
+
const runtimeSettings = await settingsWithEnabledCapabilityMcpServers(db, workspaceId, settings);
|
|
4910
|
+
const personalConnectionDelegations = await freezePersonalConnectionDelegations({
|
|
4911
|
+
db,
|
|
4912
|
+
workspaceId,
|
|
4913
|
+
settings: runtimeSettings,
|
|
4914
|
+
tools: existingSession.tools,
|
|
4915
|
+
source: personalConnectionDelegationSourceForGrant(grant)
|
|
4916
|
+
});
|
|
4745
4917
|
const delegatedServiceInitiator = serviceInitiatorForGrant(grant);
|
|
4746
4918
|
const { accepted, turn } = await postUserMessageTurn({
|
|
4747
4919
|
db,
|
|
@@ -4760,6 +4932,7 @@ async function acceptSessionUserMessage(deps, grant, workspaceId, sessionId, inp
|
|
|
4760
4932
|
reasoningEffortFallback: sessionReasoningEffort,
|
|
4761
4933
|
turnExecutionPolicy,
|
|
4762
4934
|
mcpCredentialUpdates,
|
|
4935
|
+
personalConnectionDelegations,
|
|
4763
4936
|
delivery: input.delivery ?? "send",
|
|
4764
4937
|
origin: delegatedServiceInitiator ? "operator" : input.origin ?? "human",
|
|
4765
4938
|
actor: grant.subjectId,
|
|
@@ -5101,6 +5274,19 @@ async function createValidatedScheduledTask(input) {
|
|
|
5101
5274
|
if (input.payload.rigId) {
|
|
5102
5275
|
await requireScheduledTaskRig(input.db, input.grant.workspaceId, input.payload.rigId);
|
|
5103
5276
|
}
|
|
5277
|
+
const runtimeSettings = await settingsWithEnabledCapabilityMcpServers(
|
|
5278
|
+
input.db,
|
|
5279
|
+
input.grant.workspaceId,
|
|
5280
|
+
input.settings
|
|
5281
|
+
);
|
|
5282
|
+
const personalConnectionDelegations = await freezePersonalConnectionDelegations({
|
|
5283
|
+
db: input.db,
|
|
5284
|
+
workspaceId: input.grant.workspaceId,
|
|
5285
|
+
settings: runtimeSettings,
|
|
5286
|
+
tools: agentConfig.tools,
|
|
5287
|
+
source: personalConnectionDelegationSourceForGrant(input.grant)
|
|
5288
|
+
});
|
|
5289
|
+
const creationInitiator = creationInitiatorForGrant(input.grant);
|
|
5104
5290
|
return await createScheduledTask(input.db, {
|
|
5105
5291
|
id,
|
|
5106
5292
|
accountId: input.grant.accountId,
|
|
@@ -5112,6 +5298,10 @@ async function createValidatedScheduledTask(input) {
|
|
|
5112
5298
|
runMode: input.payload.runMode,
|
|
5113
5299
|
overlapPolicy: input.payload.overlapPolicy,
|
|
5114
5300
|
agentConfig,
|
|
5301
|
+
...creationInitiator.initiator ? { createdBy: creationInitiator.initiator } : {},
|
|
5302
|
+
...creationInitiator.context ? { createdByContext: creationInitiator.context } : {},
|
|
5303
|
+
createdByActor: creationInitiator.actor ?? null,
|
|
5304
|
+
personalConnectionDelegations,
|
|
5115
5305
|
variableSetId: input.payload.variableSetId ?? null,
|
|
5116
5306
|
rigId: input.payload.rigId ?? null,
|
|
5117
5307
|
metadata: input.payload.metadata
|
|
@@ -5192,6 +5382,31 @@ async function validatedScheduledTaskUpdate(input) {
|
|
|
5192
5382
|
});
|
|
5193
5383
|
}
|
|
5194
5384
|
update.agentConfig = nextAgentConfig;
|
|
5385
|
+
const runtimeSettings = await settingsWithEnabledCapabilityMcpServers(
|
|
5386
|
+
input.db,
|
|
5387
|
+
input.existing.workspaceId,
|
|
5388
|
+
input.settings
|
|
5389
|
+
);
|
|
5390
|
+
const personalConnectionDelegations = await freezePersonalConnectionDelegations({
|
|
5391
|
+
db: input.db,
|
|
5392
|
+
workspaceId: input.existing.workspaceId,
|
|
5393
|
+
settings: runtimeSettings,
|
|
5394
|
+
tools: nextAgentConfig.tools,
|
|
5395
|
+
source: personalConnectionDelegationSourceForGrant(input.grant)
|
|
5396
|
+
});
|
|
5397
|
+
if (input.existing.reusableSessionId && input.existing.runMode === "reusable_session") {
|
|
5398
|
+
const existingDelegations = await getScheduledTaskPersonalConnectionDelegations(
|
|
5399
|
+
input.db,
|
|
5400
|
+
input.existing.workspaceId,
|
|
5401
|
+
input.existing.id
|
|
5402
|
+
);
|
|
5403
|
+
if (!personalConnectionDelegationsEqual(existingDelegations, personalConnectionDelegations)) {
|
|
5404
|
+
throw new HTTPException11(409, {
|
|
5405
|
+
message: "cannot change personal MCP connections of a task with a live reusable session; recreate the task"
|
|
5406
|
+
});
|
|
5407
|
+
}
|
|
5408
|
+
}
|
|
5409
|
+
update.personalConnectionDelegations = personalConnectionDelegations;
|
|
5195
5410
|
}
|
|
5196
5411
|
return update;
|
|
5197
5412
|
}
|
|
@@ -5202,7 +5417,18 @@ async function requireScheduledTaskForApi(db, workspaceId, taskId) {
|
|
|
5202
5417
|
}
|
|
5203
5418
|
return task;
|
|
5204
5419
|
}
|
|
5205
|
-
async function
|
|
5420
|
+
async function captureScheduledTaskRestoreState(db, task) {
|
|
5421
|
+
return {
|
|
5422
|
+
task,
|
|
5423
|
+
personalConnectionDelegations: await getScheduledTaskPersonalConnectionDelegations(
|
|
5424
|
+
db,
|
|
5425
|
+
task.workspaceId,
|
|
5426
|
+
task.id
|
|
5427
|
+
)
|
|
5428
|
+
};
|
|
5429
|
+
}
|
|
5430
|
+
async function restoreScheduledTask(db, previous) {
|
|
5431
|
+
const { task } = previous;
|
|
5206
5432
|
return await updateScheduledTask(db, task.workspaceId, task.id, {
|
|
5207
5433
|
name: task.name,
|
|
5208
5434
|
status: task.status,
|
|
@@ -5210,8 +5436,10 @@ async function restoreScheduledTask(db, task) {
|
|
|
5210
5436
|
runMode: task.runMode,
|
|
5211
5437
|
overlapPolicy: task.overlapPolicy,
|
|
5212
5438
|
agentConfig: task.agentConfig,
|
|
5439
|
+
personalConnectionDelegations: previous.personalConnectionDelegations,
|
|
5213
5440
|
reusableSessionId: task.reusableSessionId,
|
|
5214
5441
|
variableSetId: task.variableSetId,
|
|
5442
|
+
rigId: task.rigId,
|
|
5215
5443
|
metadata: task.metadata
|
|
5216
5444
|
});
|
|
5217
5445
|
}
|
|
@@ -6484,6 +6712,7 @@ export {
|
|
|
6484
6712
|
buildFleetContextForSession,
|
|
6485
6713
|
buildMarketingDailyAnalysisAgentConfig,
|
|
6486
6714
|
canonicalConfiguredModel,
|
|
6715
|
+
captureScheduledTaskRestoreState,
|
|
6487
6716
|
checkLimit,
|
|
6488
6717
|
classifyRigVerificationOutcome,
|
|
6489
6718
|
controlAgentSessionWorkstream,
|
|
@@ -6495,9 +6724,11 @@ export {
|
|
|
6495
6724
|
createRigVersionForApi,
|
|
6496
6725
|
createSessionForRequest,
|
|
6497
6726
|
createValidatedScheduledTask,
|
|
6727
|
+
creationInitiatorForGrant,
|
|
6498
6728
|
defaultSessionMcpServerIds,
|
|
6499
6729
|
deleteHumanQueuePrompt,
|
|
6500
6730
|
deleteRigForApi,
|
|
6731
|
+
directPersonalConnectionSubjectId,
|
|
6501
6732
|
disableCapability,
|
|
6502
6733
|
discoverMcpRegistryCapabilities,
|
|
6503
6734
|
editHumanQueuePrompt,
|
|
@@ -6505,6 +6736,7 @@ export {
|
|
|
6505
6736
|
enabledCapabilityMcpToolRefs,
|
|
6506
6737
|
executeRunOnSelfhostedMachine,
|
|
6507
6738
|
filenameForMimeType,
|
|
6739
|
+
freezePersonalConnectionDelegations,
|
|
6508
6740
|
getActorNewSessionDraft,
|
|
6509
6741
|
getCapabilityPack,
|
|
6510
6742
|
getHumanComposerDraft,
|
|
@@ -6534,6 +6766,11 @@ export {
|
|
|
6534
6766
|
normalizeResources,
|
|
6535
6767
|
officialMcpRegistryUrl,
|
|
6536
6768
|
openGeniSlackBotMetadata,
|
|
6769
|
+
personalConnectionDelegationForServer,
|
|
6770
|
+
personalConnectionDelegationSourceForGrant,
|
|
6771
|
+
personalConnectionDelegationsEqual,
|
|
6772
|
+
personalConnectionDelegationsFromParent,
|
|
6773
|
+
personalConnectionDelegationsFromVisibleConnections,
|
|
6537
6774
|
postUserMessageTurn,
|
|
6538
6775
|
promoteSetupAppendChange,
|
|
6539
6776
|
promoteVerifiedDefinitionEditChangeForApi,
|
|
@@ -6575,6 +6812,7 @@ export {
|
|
|
6575
6812
|
scheduledTaskTemporalScheduleId,
|
|
6576
6813
|
scheduledTaskToolsProvided,
|
|
6577
6814
|
scheduledTaskTriggerToken,
|
|
6815
|
+
selectedPersonalConnectionServers,
|
|
6578
6816
|
sendAgentSessionMessage,
|
|
6579
6817
|
sessionSpawnDenialEnvelope,
|
|
6580
6818
|
sessionWithEffectiveToolPolicy,
|
|
@@ -6604,6 +6842,7 @@ export {
|
|
|
6604
6842
|
validateVariableSetAttachment,
|
|
6605
6843
|
validatedScheduledTaskUpdate,
|
|
6606
6844
|
withDefaultEnabledCapabilityMcpTools,
|
|
6845
|
+
withFrozenPersonalConnectionDelegations,
|
|
6607
6846
|
workflowIdForSession,
|
|
6608
6847
|
workspaceSessionToolPolicyDefaultServerIds,
|
|
6609
6848
|
workspaceSessionToolPolicyServerIds,
|