@opengeni/core 0.21.2 → 0.24.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.
Files changed (123) hide show
  1. package/dist/access/index.d.ts +9 -1
  2. package/dist/application/new-session-drafts.d.ts +1 -1
  3. package/dist/application/session-commands.d.ts +9 -4
  4. package/dist/billing/limits.d.ts +1 -1
  5. package/dist/chunk-6WKPWE5S.js +2380 -0
  6. package/dist/chunk-6WKPWE5S.js.map +1 -0
  7. package/dist/chunk-JJU6I5XD.js +2713 -0
  8. package/dist/chunk-JJU6I5XD.js.map +1 -0
  9. package/dist/chunk-NYPMQ7NO.js +2270 -0
  10. package/dist/chunk-NYPMQ7NO.js.map +1 -0
  11. package/dist/dependencies.d.ts +26 -6
  12. package/dist/domain/capabilities.d.ts +35 -3
  13. package/dist/domain/company-profile-durable-learning-adapter.d.ts +39 -0
  14. package/dist/domain/durable-learning-slack-publication.d.ts +72 -0
  15. package/dist/domain/editable-artifacts/agent-application.d.ts +192 -0
  16. package/dist/domain/editable-artifacts/durable-export-postgres.d.ts +4 -0
  17. package/dist/domain/editable-artifacts/durable-export.d.ts +212 -0
  18. package/dist/domain/editable-artifacts/errors.d.ts +47 -0
  19. package/dist/domain/editable-artifacts/hash.d.ts +11 -0
  20. package/dist/domain/editable-artifacts/in-memory.d.ts +99 -0
  21. package/dist/domain/editable-artifacts/index.d.ts +14 -0
  22. package/dist/domain/editable-artifacts/ports.d.ts +341 -0
  23. package/dist/domain/editable-artifacts/postgres-adapters.d.ts +13 -0
  24. package/dist/domain/editable-artifacts/service.d.ts +105 -0
  25. package/dist/domain/editable-artifacts/snapshot-compaction.d.ts +44 -0
  26. package/dist/domain/editable-artifacts/snapshot-verifier-genesis.d.ts +50 -0
  27. package/dist/domain/editable-artifacts/snapshot-verifier-materialization.d.ts +21 -0
  28. package/dist/domain/editable-artifacts/snapshot-verifier.d.ts +118 -0
  29. package/dist/domain/editable-artifacts/types.d.ts +410 -0
  30. package/dist/domain/memory-slack-delivery.d.ts +19 -0
  31. package/dist/domain/memory-slack-publication.d.ts +0 -2
  32. package/dist/domain/packs.d.ts +29 -1
  33. package/dist/domain/personal-connection-delegations.d.ts +9 -1
  34. package/dist/domain/scheduled-tasks.d.ts +27 -3
  35. package/dist/domain/session-tool-policy.d.ts +2 -2
  36. package/dist/domain/sessions.d.ts +44 -10
  37. package/dist/domain/skill-imports.d.ts +32 -0
  38. package/dist/domain/slack-publication-secret-safety.d.ts +8 -0
  39. package/dist/domain/timeline-annotations.d.ts +5 -0
  40. package/dist/domain/video-generation-capabilities.d.ts +9 -0
  41. package/dist/domain/video-generation.d.ts +47 -0
  42. package/dist/editable-artifact-live/application.d.ts +69 -0
  43. package/dist/editable-artifact-live/errors.d.ts +1 -0
  44. package/dist/editable-artifact-live/index.d.ts +8 -0
  45. package/dist/editable-artifact-live/outbox-dispatcher.d.ts +162 -0
  46. package/dist/editable-artifact-live/ports.d.ts +100 -0
  47. package/dist/editable-artifact-live/server.d.ts +71 -0
  48. package/dist/editable-artifact-live/ticket.d.ts +40 -0
  49. package/dist/editable-artifact-live/types.d.ts +213 -0
  50. package/dist/editable-artifact-live/wire.d.ts +34 -0
  51. package/dist/editable-artifact-live.d.ts +2 -0
  52. package/dist/editable-artifact-live.js +58 -0
  53. package/dist/editable-artifact-live.js.map +1 -0
  54. package/dist/editable-artifacts.d.ts +2 -0
  55. package/dist/editable-artifacts.js +179 -0
  56. package/dist/editable-artifacts.js.map +1 -0
  57. package/dist/index.d.ts +35 -25
  58. package/dist/index.js +3184 -652
  59. package/dist/index.js.map +1 -1
  60. package/dist/managed-session.d.ts +53 -0
  61. package/dist/rigs/index.d.ts +1 -1
  62. package/dist/rigs/provider-images.d.ts +31 -0
  63. package/dist/sandbox/fleet.d.ts +9 -1
  64. package/dist/sandbox/routing.d.ts +1 -0
  65. package/dist/session-authorization.d.ts +10 -1
  66. package/dist/workflow-wake-contract.d.ts +7 -0
  67. package/package.json +18 -10
  68. package/src/access/index.ts +43 -3
  69. package/src/application/new-session-drafts.ts +2 -0
  70. package/src/application/session-commands.ts +217 -116
  71. package/src/dependencies.ts +30 -2
  72. package/src/domain/capabilities.ts +672 -218
  73. package/src/domain/company-profile-durable-learning-adapter.ts +221 -0
  74. package/src/domain/durable-learning-slack-publication.ts +202 -0
  75. package/src/domain/editable-artifacts/agent-application.ts +687 -0
  76. package/src/domain/editable-artifacts/durable-export-postgres.ts +139 -0
  77. package/src/domain/editable-artifacts/durable-export.ts +734 -0
  78. package/src/domain/editable-artifacts/errors.ts +115 -0
  79. package/src/domain/editable-artifacts/hash.ts +131 -0
  80. package/src/domain/editable-artifacts/in-memory.ts +1662 -0
  81. package/src/domain/editable-artifacts/index.ts +14 -0
  82. package/src/domain/editable-artifacts/ports.ts +462 -0
  83. package/src/domain/editable-artifacts/postgres-adapters.ts +49 -0
  84. package/src/domain/editable-artifacts/service.ts +2402 -0
  85. package/src/domain/editable-artifacts/snapshot-compaction.ts +246 -0
  86. package/src/domain/editable-artifacts/snapshot-verifier-genesis.ts +235 -0
  87. package/src/domain/editable-artifacts/snapshot-verifier-materialization.ts +74 -0
  88. package/src/domain/editable-artifacts/snapshot-verifier.ts +687 -0
  89. package/src/domain/editable-artifacts/types.ts +835 -0
  90. package/src/domain/insights.ts +136 -33
  91. package/src/domain/memory-slack-delivery.ts +204 -0
  92. package/src/domain/memory-slack-publication.ts +10 -19
  93. package/src/domain/packs.ts +266 -5
  94. package/src/domain/personal-connection-delegations.ts +97 -6
  95. package/src/domain/resources.ts +10 -20
  96. package/src/domain/scheduled-tasks.ts +365 -25
  97. package/src/domain/session-tool-policy.ts +8 -2
  98. package/src/domain/sessions.ts +388 -155
  99. package/src/domain/skill-imports.ts +350 -0
  100. package/src/domain/slack-publication-secret-safety.ts +42 -0
  101. package/src/domain/timeline-annotations.ts +204 -0
  102. package/src/domain/video-generation-capabilities.ts +69 -0
  103. package/src/domain/video-generation.ts +249 -0
  104. package/src/editable-artifact-live/application.ts +182 -0
  105. package/src/editable-artifact-live/errors.ts +4 -0
  106. package/src/editable-artifact-live/index.ts +8 -0
  107. package/src/editable-artifact-live/outbox-dispatcher.ts +916 -0
  108. package/src/editable-artifact-live/ports.ts +139 -0
  109. package/src/editable-artifact-live/server.ts +1707 -0
  110. package/src/editable-artifact-live/ticket.ts +217 -0
  111. package/src/editable-artifact-live/types.ts +286 -0
  112. package/src/editable-artifact-live/wire.ts +95 -0
  113. package/src/editable-artifact-live.ts +2 -0
  114. package/src/editable-artifacts.ts +2 -0
  115. package/src/index.ts +14 -0
  116. package/src/managed-auth-type.ts +4 -3
  117. package/src/managed-session.ts +36 -0
  118. package/src/rigs/index.ts +26 -19
  119. package/src/rigs/provider-images.ts +110 -0
  120. package/src/sandbox/fleet.ts +56 -1
  121. package/src/sandbox/routing.ts +32 -3
  122. package/src/session-authorization.ts +20 -0
  123. package/src/workflow-wake-contract.ts +8 -0
@@ -0,0 +1,53 @@
1
+ import type { Context } from "hono";
2
+ import type { ManagedAuth } from "./managed-auth-type.js";
3
+ /**
4
+ * Read a Better Auth session without bypassing its sliding-cookie renewal.
5
+ *
6
+ * Better Auth can refresh the durable session while resolving `getSession`.
7
+ * Programmatic callers must explicitly request and forward the returned cookie
8
+ * headers; the HTTP handler does this automatically, but direct API calls do not.
9
+ */
10
+ export declare function getManagedSession(c: Context, auth: ManagedAuth): Promise<{
11
+ session: {
12
+ id: string;
13
+ createdAt: Date;
14
+ updatedAt: Date;
15
+ userId: string;
16
+ expiresAt: Date;
17
+ token: string;
18
+ ipAddress?: string | null | undefined;
19
+ userAgent?: string | null | undefined;
20
+ } | {
21
+ [x: string]: any;
22
+ [x: number]: any;
23
+ [x: symbol]: any;
24
+ id: string;
25
+ createdAt: Date;
26
+ updatedAt: Date;
27
+ userId: string;
28
+ expiresAt: Date;
29
+ token: string;
30
+ ipAddress?: string | null | undefined;
31
+ userAgent?: string | null | undefined;
32
+ };
33
+ user: {
34
+ id: string;
35
+ createdAt: Date;
36
+ updatedAt: Date;
37
+ email: string;
38
+ emailVerified: boolean;
39
+ name: string;
40
+ image?: string | null | undefined;
41
+ } | {
42
+ [x: string]: any;
43
+ [x: number]: any;
44
+ [x: symbol]: any;
45
+ id: string;
46
+ createdAt: Date;
47
+ updatedAt: Date;
48
+ email: string;
49
+ emailVerified: boolean;
50
+ name: string;
51
+ image?: string | null | undefined;
52
+ };
53
+ } | null>;
@@ -1,5 +1,6 @@
1
1
  import type { AccessGrant, CreateRigRequest, RigDefinitionEditPayload, ProposeRigChangeRequest, Rig, RigChange, RigVersion, UpdateRigRequest } from "@opengeni/contracts";
2
2
  import { type Database } from "@opengeni/db";
3
+ export * from "./provider-images.js";
3
4
  export declare const MAX_RIGS_PER_WORKSPACE = 50;
4
5
  export declare const MAX_CHECKS_PER_RIG = 100;
5
6
  export declare const MAX_CREDENTIAL_HOOKS_PER_RIG = 50;
@@ -54,4 +55,3 @@ export declare function createRigVersionForApi(deps: RigServices, grant: AccessG
54
55
  export declare function activateRigVersionForApi(deps: RigServices, grant: AccessGrant, rig: Rig, versionId: string): Promise<RigVersion>;
55
56
  export declare function listRigVersionsForApi(deps: RigServices, workspaceId: string, rigId: string): Promise<RigVersion[]>;
56
57
  export declare function listRigChangesForApi(deps: RigServices, workspaceId: string, rigId: string, limit?: number): Promise<RigChange[]>;
57
- export {};
@@ -0,0 +1,31 @@
1
+ import { type RigChangeVerification, type RigProviderImage, type RigProviderImages, type RigVersion, type SandboxBackend } from "@opengeni/contracts";
2
+ export type RigProviderImageDefinition = Pick<RigVersion, "image" | "setupScript" | "checks" | "credentialHooks" | "defaultVariableSetIds">;
3
+ export declare function rigProviderImageProviderBindingKeyHash(bindingKey: string): string;
4
+ export declare function rigProviderImageSetupHash(definition: Pick<RigProviderImageDefinition, "setupScript">): string;
5
+ /**
6
+ * Hash every exact rig-definition input that can affect whether a provider
7
+ * image may be reused. Credential values and variable-set contents are
8
+ * intentionally absent: verification never injects them into the build box.
9
+ * Their declared hook/set identities still participate so a new rig version
10
+ * cannot silently inherit an older build record.
11
+ */
12
+ export declare function rigProviderImageContentHash(input: {
13
+ backend: SandboxBackend;
14
+ sourceImage: string | null;
15
+ definition: RigProviderImageDefinition;
16
+ }): string;
17
+ /** Modal's patched snapshot API accepts a caller-owned UUID idempotency key.
18
+ * v2 denotes images proven by a separate cold boot before publication. */
19
+ export declare function rigProviderImageBuildRequestId(input: {
20
+ targetId: string;
21
+ backend: SandboxBackend;
22
+ contentHash: string;
23
+ }): string;
24
+ export declare function rigProviderImageMatchesDefinition(image: RigProviderImage, definition: RigProviderImageDefinition): boolean;
25
+ /**
26
+ * Promotion copies only a finalized, structurally valid build record whose
27
+ * hashes match the exact version definition being inserted. A malformed or
28
+ * stale optimization record is discarded; the version remains correct and
29
+ * falls back to runtime setup.
30
+ */
31
+ export declare function rigProviderImagesFromVerification(verification: RigChangeVerification | null, definition: RigProviderImageDefinition): RigProviderImages;
@@ -1,7 +1,7 @@
1
1
  import type { Settings } from "@opengeni/config";
2
2
  import { type Database, type SandboxRecord } from "@opengeni/db";
3
3
  import type { EventBus } from "@opengeni/events";
4
- import { type BackendUnresolvableCode, type ControlRpc, type SelfhostedRelayConfig } from "@opengeni/runtime/sandbox";
4
+ import { type BackendUnresolvableCode, type ControlRpc, type SelfhostedRelayConfig, type SelfhostedOpStreamDeps } from "@opengeni/runtime/sandbox";
5
5
  export type FleetServices = {
6
6
  db: Database;
7
7
  settings: Settings;
@@ -44,6 +44,7 @@ export declare function buildFleetContextForSession(deps: {
44
44
  }): Promise<FleetContext>;
45
45
  /** The dominant liveness of a fleet member, surfaced to the dock + the agent. */
46
46
  export type FleetLiveness = "online" | "reconnecting" | "offline";
47
+ export type FleetOperationAvailability = "ready" | "wakeable" | "recovering" | "unavailable";
47
48
  /**
48
49
  * A fleet member as the agent + the dock see it (the M8b/M9 UI seam — the
49
50
  * `sandboxes_list` response entry the dock renders). STABLE shape: the dock keys
@@ -65,6 +66,11 @@ export type FleetSandboxEntry = {
65
66
  enrollmentId: string | null;
66
67
  /** Whether this target can be attached/swapped to right now (live + addressable). */
67
68
  attachable: boolean;
69
+ /** Whether an ordinary shell/files operation can use this target. This is
70
+ * deliberately separate from `attachable`: an idle managed home sandbox can
71
+ * be wakeable even while its holderless lease is cold/draining and therefore
72
+ * not an already-live swap target. */
73
+ operationAvailability: FleetOperationAvailability;
68
74
  /** Selfhosted only: whether whole-machine + screen-control consent is acked. */
69
75
  consented?: boolean;
70
76
  /** Selfhosted only: whether a display (real/Xvfb) is present. */
@@ -154,6 +160,8 @@ export type RunOnSelfhostedMachine = {
154
160
  controlTimeoutMs: number;
155
161
  /** Longer agent-side process deadline for exec. */
156
162
  execTimeoutMs: number;
163
+ /** Streaming transport required when execTimeoutMs is 0 (unbounded). */
164
+ opStream?: SelfhostedOpStreamDeps;
157
165
  };
158
166
  /**
159
167
  * Execute the one-off machine operation once the workspace/enrollment lookup has
@@ -7,6 +7,7 @@ export type ChannelARoutingServices = {
7
7
  settings: Settings;
8
8
  bus?: EventBus;
9
9
  onSandboxOperation?: RoutingSandboxOperationObserver;
10
+ waitSignal?: AbortSignal;
10
11
  };
11
12
  /** Map the deployment relay URL to the leaf's `SelfhostedRelayConfig` shape. The
12
13
  * relay URL (`OPENGENI_SELFHOSTED_RELAY_URL`) may carry a path (the relay's wss
@@ -1,5 +1,6 @@
1
1
  import { SessionAuthorizationActor, SessionAuthorizationListScope, type AccessGrant, type SessionAuthorizationOperation, type SessionAuthorizationSurface, type SessionAuthorizationTarget } from "@opengeni/contracts";
2
- import type { AppDependencies } from "./dependencies";
2
+ import { type Database } from "@opengeni/db";
3
+ import type { AppDependencies } from "./dependencies.js";
3
4
  export type SessionAuthorizationDependencies = Pick<AppDependencies, "db" | "sessionAuthorization">;
4
5
  /** Maximum time an omitted host hint leaves a live session stream unchecked. */
5
6
  export declare const SESSION_AUTHORIZATION_DEFAULT_REAUTHORIZE_MS = 15000;
@@ -18,6 +19,14 @@ export type ResolvedSessionAuthorization = {
18
19
  relatedSessionAccess: "target" | "root";
19
20
  reauthorizeAfterMs: number | null;
20
21
  };
22
+ /**
23
+ * Prove that a first-party request belongs to the exact currently active
24
+ * attempt of the named caller session. Unlike the optional embedding-host ACL
25
+ * port, this database fence is mandatory for high-trust operations.
26
+ */
27
+ export declare function requireLiveAgentAttemptAuthorization(db: Database, grant: AccessGrant, callerSessionId: string): Promise<Extract<SessionAuthorizationActor, {
28
+ kind: "agent_attempt";
29
+ }>>;
21
30
  /**
22
31
  * Resolve and enforce the host ACL for one session. The target and agent actor
23
32
  * are reconstructed from workspace-scoped durable state. A request can supply
@@ -2,3 +2,10 @@
2
2
  export declare const SESSION_WORKFLOW_WAKE_DISPATCHER_SCHEDULE_ID = "opengeni-session-workflow-wake-dispatcher";
3
3
  export declare const SESSION_WORKFLOW_WAKE_DISPATCHER_WORKFLOW_TYPE = "sessionWorkflowWakeDispatcherWorkflow";
4
4
  export declare const SESSION_WORKFLOW_WAKE_DISPATCHER_PERIOD_MS = 10000;
5
+ /**
6
+ * Temporal delivers activity cancellation through heartbeats. Keep both the
7
+ * activity's local heartbeat timer and the worker's SDK throttle at this bound
8
+ * so the end-to-end Pause/Steer physical-cancellation contract is not already
9
+ * exhausted before sandbox/tool quiescence and replacement admission begin.
10
+ */
11
+ export declare const TURN_ACTIVITY_CANCELLATION_HEARTBEAT_INTERVAL_MS = 500;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/core",
3
- "version": "0.21.2",
3
+ "version": "0.24.1",
4
4
  "description": "OpenGeni framework-agnostic core: the domain, access, and billing layers (neutral access, off-HTTP V2 surface). Behavior-preserving extraction from apps/api — keeps Hono's HTTPException for error throwing (typed-errors cleanup deferred).",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -21,6 +21,14 @@
21
21
  ".": {
22
22
  "types": "./dist/index.d.ts",
23
23
  "import": "./dist/index.js"
24
+ },
25
+ "./editable-artifacts": {
26
+ "types": "./dist/editable-artifacts.d.ts",
27
+ "import": "./dist/editable-artifacts.js"
28
+ },
29
+ "./editable-artifact-live": {
30
+ "types": "./dist/editable-artifact-live.d.ts",
31
+ "import": "./dist/editable-artifact-live.js"
24
32
  }
25
33
  },
26
34
  "publishConfig": {
@@ -34,15 +42,15 @@
34
42
  },
35
43
  "dependencies": {
36
44
  "@modelcontextprotocol/sdk": "^1.29.0",
37
- "@opengeni/codex": "^0.2.11",
38
- "@opengeni/config": "^0.11.0",
39
- "@opengeni/contracts": "^0.39.0",
40
- "@opengeni/db": "^0.28.1",
41
- "@opengeni/documents": "^0.5.10",
42
- "@opengeni/events": "^0.3.80",
43
- "@opengeni/observability": "^0.5.0",
44
- "@opengeni/runtime": "^0.18.17",
45
- "@opengeni/storage": "^0.2.68",
45
+ "@opengeni/codex": "^0.2.15",
46
+ "@opengeni/config": "^0.13.2",
47
+ "@opengeni/contracts": "^0.44.1",
48
+ "@opengeni/db": "^0.31.1",
49
+ "@opengeni/documents": "^0.5.32",
50
+ "@opengeni/events": "^0.3.103",
51
+ "@opengeni/observability": "^0.6.2",
52
+ "@opengeni/runtime": "^0.19.2",
53
+ "@opengeni/storage": "^0.2.87",
46
54
  "hono": "^4.12.18"
47
55
  },
48
56
  "engines": {
@@ -17,6 +17,7 @@ import {
17
17
  import type { Context } from "hono";
18
18
  import { HTTPException } from "hono/http-exception";
19
19
  import type { ManagedAuth } from "../managed-auth-type";
20
+ import { getManagedSession } from "../managed-session";
20
21
 
21
22
  const bearerPrefix = "Bearer ";
22
23
 
@@ -143,10 +144,51 @@ export function requirePermission(grant: AccessGrant, permission: Permission): v
143
144
  }
144
145
  }
145
146
 
147
+ /**
148
+ * Require a permission to be present literally on the grant. This deliberately
149
+ * does not expand workspace:admin or deprecated aliases and is reserved for
150
+ * authorities, such as plaintext secret reads, that old broad grants must not
151
+ * acquire implicitly.
152
+ */
153
+ export function requireLiteralPermission(grant: AccessGrant, permission: Permission): void {
154
+ if (!hasLiteralPermission(grant.permissions, permission)) {
155
+ throw new HTTPException(403, {
156
+ message: `missing literal permission: ${permission}`,
157
+ });
158
+ }
159
+ }
160
+
161
+ export function hasLiteralPermission(permissions: Permission[], permission: Permission): boolean {
162
+ return permissions.includes(permission);
163
+ }
164
+
146
165
  export function hasPermission(permissions: Permission[], permission: Permission): boolean {
166
+ if (permission === "secrets:read") {
167
+ return permissions.includes("secrets:read");
168
+ }
147
169
  const aliases: Partial<Record<Permission, Permission[]>> = {
148
170
  "variable-sets:use": ["environments:use" as Permission],
149
171
  "variable-sets:manage": ["environments:manage" as Permission],
172
+ "variable-sets:list": [
173
+ "variable-sets:use",
174
+ "variable-sets:manage",
175
+ "environments:use" as Permission,
176
+ "environments:manage" as Permission,
177
+ ],
178
+ "variable-sets:read": [
179
+ "variable-sets:use",
180
+ "variable-sets:manage",
181
+ "environments:use" as Permission,
182
+ "environments:manage" as Permission,
183
+ ],
184
+ "variable-sets:write": ["variable-sets:manage", "environments:manage" as Permission],
185
+ "secrets:list": [
186
+ "variable-sets:use",
187
+ "variable-sets:manage",
188
+ "environments:use" as Permission,
189
+ "environments:manage" as Permission,
190
+ ],
191
+ "secrets:write": ["variable-sets:manage", "environments:manage" as Permission],
150
192
  };
151
193
  return (
152
194
  permissions.includes(permission) ||
@@ -210,9 +252,7 @@ async function resolveAccessContext(c: Context, deps: AccessDeps): Promise<Acces
210
252
  }
211
253
 
212
254
  if (deps.managedAuth) {
213
- const session = await deps.managedAuth.api.getSession({
214
- headers: c.req.raw.headers,
215
- });
255
+ const session = await getManagedSession(c, deps.managedAuth);
216
256
  if (session?.user) {
217
257
  return await ensureManagedAccessForUser(deps.db, {
218
258
  userId: session.user.id,
@@ -67,6 +67,7 @@ async function hydrateNewSessionDraft(
67
67
  deps.db,
68
68
  workspaceId,
69
69
  deps.settings,
70
+ { subjectId: grant.subjectId },
70
71
  );
71
72
  const resources = [] as NewSessionDraftValue["resources"];
72
73
  for (const resource of mapped.resources) {
@@ -200,6 +201,7 @@ export async function saveActorNewSessionDraft(
200
201
  deps.db,
201
202
  workspaceId,
202
203
  deps.settings,
204
+ { subjectId: grant.subjectId },
203
205
  );
204
206
  const resources = normalizeResources(input.resources);
205
207
  const tools = toolsProvided ? validateToolRefs(input.tools, runtimeSettings) : [];