@iblai/data-layer 1.21.0 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -39082,13 +39082,13 @@ const SPEND_CAPS_REDUCER_PATH = 'spendCapsApiSlice';
39082
39082
  * provider rate limit, which also uses status 429.
39083
39083
  */
39084
39084
  const SPEND_CAP_EXCEEDED_ERROR_CODE = 'spend_cap_exceeded';
39085
- const encodePathSegment$2 = (value) => encodeURIComponent(value);
39086
- const tenantSpendCapPath = (org) => `/api/ai-mentor/orgs/${encodePathSegment$2(org)}/spend-caps/tenant/`;
39087
- const agentSpendCapPath = (org, mentorId) => `/api/ai-mentor/orgs/${encodePathSegment$2(org)}/agents/${encodePathSegment$2(mentorId)}/spend-cap/`;
39088
- const agentUserSpendCapsPath = (org, mentorId) => `/api/ai-mentor/orgs/${encodePathSegment$2(org)}/agents/${encodePathSegment$2(mentorId)}/spend-caps/users/`;
39089
- const userSpendCapPath = (org, mentorId, username) => `${agentUserSpendCapsPath(org, mentorId)}${encodePathSegment$2(username)}/`;
39090
- const spendCapStatusPath = (org, userId) => `/api/ai-mentor/orgs/${encodePathSegment$2(org)}/spend-caps/status/${encodePathSegment$2(userId)}/`;
39091
- const agentSpendCapsListPath = (org) => `/api/ai-mentor/orgs/${encodePathSegment$2(org)}/spend-caps/agents/`;
39085
+ const encodePathSegment$3 = (value) => encodeURIComponent(value);
39086
+ const tenantSpendCapPath = (org) => `/api/ai-mentor/orgs/${encodePathSegment$3(org)}/spend-caps/tenant/`;
39087
+ const agentSpendCapPath = (org, mentorId) => `/api/ai-mentor/orgs/${encodePathSegment$3(org)}/agents/${encodePathSegment$3(mentorId)}/spend-cap/`;
39088
+ const agentUserSpendCapsPath = (org, mentorId) => `/api/ai-mentor/orgs/${encodePathSegment$3(org)}/agents/${encodePathSegment$3(mentorId)}/spend-caps/users/`;
39089
+ const userSpendCapPath = (org, mentorId, username) => `${agentUserSpendCapsPath(org, mentorId)}${encodePathSegment$3(username)}/`;
39090
+ const spendCapStatusPath = (org, userId) => `/api/ai-mentor/orgs/${encodePathSegment$3(org)}/spend-caps/status/${encodePathSegment$3(userId)}/`;
39091
+ const agentSpendCapsListPath = (org) => `/api/ai-mentor/orgs/${encodePathSegment$3(org)}/spend-caps/agents/`;
39092
39092
  const SPEND_CAPS_ENDPOINTS = {
39093
39093
  GET_TENANT_SPEND_CAP: {
39094
39094
  service: exports.SERVICES.DM,
@@ -42473,7 +42473,7 @@ const MONETIZATION_ENDPOINTS = {
42473
42473
  path: (key, type, id, priceId) => `${BILLING_BASE}/${key}/items/${type}/${id}/paywall/prices/${priceId}/`,
42474
42474
  service: exports.SERVICES.DM,
42475
42475
  },
42476
- // Flow 4 — Public Pricing (No Auth)
42476
+ // Flow 4 — Public Pricing (No Authentication)
42477
42477
  PUBLIC_PRICING: {
42478
42478
  path: (key, type, id) => `${BILLING_BASE}/${key}/items/${type}/${id}/pricing/`,
42479
42479
  service: exports.SERVICES.DM,
@@ -46576,11 +46576,11 @@ const VERCEL_SPA = 'vercel';
46576
46576
  // platform-wide listing, which is why "add a domain" can only offer the caller's
46577
46577
  // own deployed apps.
46578
46578
  const HOSTING_REDUCER_PATH = 'hostingApiSlice';
46579
- const encodePathSegment$1 = (value) => encodeURIComponent(value);
46580
- const userHostingPath = (org, username) => `/api/ai-mentor/orgs/${encodePathSegment$1(org)}/users/${encodePathSegment$1(username)}/providers/vercel/hosting`;
46579
+ const encodePathSegment$2 = (value) => encodeURIComponent(value);
46580
+ const userHostingPath = (org, username) => `/api/ai-mentor/orgs/${encodePathSegment$2(org)}/users/${encodePathSegment$2(username)}/providers/vercel/hosting`;
46581
46581
  const hostingProjectsPath = (org, username) => `${userHostingPath(org, username)}/deployment/`;
46582
46582
  const hostingProjectDomainsPath = (org, username) => `${userHostingPath(org, username)}/dns/`;
46583
- const hostingDomainPath = (org, domainId) => `/api/ai-mentor/orgs/${encodePathSegment$1(org)}/providers/vercel/hosting/domains/${domainId}/`;
46583
+ const hostingDomainPath = (org, domainId) => `/api/ai-mentor/orgs/${encodePathSegment$2(org)}/providers/vercel/hosting/domains/${domainId}/`;
46584
46584
  const HOSTING_ENDPOINTS = {
46585
46585
  GET_HOSTING_PROJECTS: {
46586
46586
  service: exports.SERVICES.DM,
@@ -47421,8 +47421,8 @@ exports.recommendationPromptTypeEnum = void 0;
47421
47421
  recommendationPromptTypeEnum["catalog"] = "catalog";
47422
47422
  })(exports.recommendationPromptTypeEnum || (exports.recommendationPromptTypeEnum = {}));
47423
47423
 
47424
- const encodePathSegment = (value) => encodeURIComponent(value);
47425
- const periodicAgentsListPath = ({ org, userId }) => `/api/ai-mentor/orgs/${encodePathSegment(org)}/users/${encodePathSegment(userId)}/periodic-agents/`;
47424
+ const encodePathSegment$1 = (value) => encodeURIComponent(value);
47425
+ const periodicAgentsListPath = ({ org, userId }) => `/api/ai-mentor/orgs/${encodePathSegment$1(org)}/users/${encodePathSegment$1(userId)}/periodic-agents/`;
47426
47426
  const periodicAgentsListParams = ({ enabled, mentorId, ordering, page, pageSize, parentMentorId, parentSessionId, previousAgent, previousAgentStatus, search, status, title, username, startDate, endDate, }) => ({
47427
47427
  enabled,
47428
47428
  mentor_id: mentorId,
@@ -49115,6 +49115,357 @@ function useUserLlmTraceObservations(scope, options) {
49115
49115
  return useUserLlmUsageObservations(base && traceId ? { ...base, resource: 'observations', trace_id: traceId, limit } : null, options);
49116
49116
  }
49117
49117
 
49118
+ // Backend contract: the Virtual Machine Shell network features on iblai-dm-pro.
49119
+ // An agent with `enable_virtual_machine` runs its `execute` tool in an isolated
49120
+ // per-chat-run Linux VM that has no network by default. Two org-level records,
49121
+ // both under /api/ai-account/orgs/{org}/, decide what the VM can reach and
49122
+ // which credentials it can use:
49123
+ // 1. Network policies — virtual-machine-network-policy/ — named, reusable
49124
+ // `host:port` allowlists an agent binds under the `custom` egress profile.
49125
+ // 2. VM secrets — virtual-machine-secret/ — API keys the VM can use but never
49126
+ // read; the real value is swapped in on the wire, only for HTTPS requests to
49127
+ // the secret's own hosts.
49128
+ // Both are bound to an agent through the mentor-settings endpoint
49129
+ // (`virtual_machine_egress`, `virtual_machine_network_policy_id`,
49130
+ // `virtual_machine_secret_ids`) — see ./types.ts.
49131
+ const VIRTUAL_MACHINE_REDUCER_PATH = 'virtualMachineApiSlice';
49132
+ const VIRTUAL_MACHINE_QUERY_KEYS = {
49133
+ NETWORK_POLICIES: 'VirtualMachineNetworkPolicies',
49134
+ SECRETS: 'VirtualMachineSecrets',
49135
+ };
49136
+ const encodePathSegment = (value) => encodeURIComponent(value);
49137
+ const VIRTUAL_MACHINE_ENDPOINTS = {
49138
+ /** GET (list) / POST (create) / PATCH (update by `id`) / DELETE (by `id`). */
49139
+ NETWORK_POLICIES: {
49140
+ service: exports.SERVICES.DM,
49141
+ path: (org) => `/api/ai-account/orgs/${encodePathSegment(org)}/virtual-machine-network-policy/`,
49142
+ },
49143
+ /** GET (list) / POST (create) / PATCH (update by `env_var`) / DELETE (by `env_var`). */
49144
+ SECRETS: {
49145
+ service: exports.SERVICES.DM,
49146
+ path: (org) => `/api/ai-account/orgs/${encodePathSegment(org)}/virtual-machine-secret/`,
49147
+ },
49148
+ };
49149
+ /**
49150
+ * RBAC permission names the backend checks on each endpoint. Listed for
49151
+ * reference — the UI gates on the list call's 403 rather than on these.
49152
+ */
49153
+ const VIRTUAL_MACHINE_PERMISSIONS = {
49154
+ NETWORK_POLICIES: {
49155
+ LIST: 'Ibl.Mentor/VirtualMachineNetworkPolicies/list',
49156
+ WRITE: 'Ibl.Mentor/VirtualMachineNetworkPolicies/write',
49157
+ DELETE: 'Ibl.Mentor/VirtualMachineNetworkPolicies/delete',
49158
+ },
49159
+ SECRETS: {
49160
+ LIST: 'Ibl.Mentor/VirtualMachineSecrets/list',
49161
+ WRITE: 'Ibl.Mentor/VirtualMachineSecrets/write',
49162
+ DELETE: 'Ibl.Mentor/VirtualMachineSecrets/delete',
49163
+ },
49164
+ };
49165
+ /** Egress profiles, in the order the UI lists them. `none` is the default. */
49166
+ const VIRTUAL_MACHINE_EGRESS_PROFILES = ['none', 'registries', 'public', 'custom'];
49167
+ /**
49168
+ * Fast client-side check for a `host:port` entry. The backend is authoritative
49169
+ * (it also rejects wildcards, schemes, paths and the reserved hosts below), so
49170
+ * its message is always surfaced when it disagrees.
49171
+ */
49172
+ const VIRTUAL_MACHINE_HOST_PORT_PATTERN = /^[a-z0-9]([a-z0-9.-]*[a-z0-9])?:\d{1,5}$/i;
49173
+ /** Hostnames the backend refuses in any allowlist. */
49174
+ const VIRTUAL_MACHINE_REJECTED_HOSTS = [
49175
+ 'localhost',
49176
+ 'metadata',
49177
+ 'metadata.google.internal',
49178
+ 'instance-data',
49179
+ 'instance-data.ec2.internal',
49180
+ ];
49181
+ /** Hostname suffixes the backend refuses in any allowlist. */
49182
+ const VIRTUAL_MACHINE_REJECTED_HOST_SUFFIXES = [
49183
+ '.local',
49184
+ '.internal',
49185
+ '.localhost',
49186
+ ];
49187
+ /** `env_var` of a VM secret: a POSIX-style environment variable name. */
49188
+ const VIRTUAL_MACHINE_ENV_VAR_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
49189
+ /** A network policy holds between 1 and 100 hosts. */
49190
+ const VIRTUAL_MACHINE_MAX_POLICY_HOSTS = 100;
49191
+ /** An agent may bind at most 20 VM secrets. */
49192
+ const VIRTUAL_MACHINE_MAX_SECRETS_PER_MENTOR = 20;
49193
+ /** A pasted secret value must be at least this long. */
49194
+ const VIRTUAL_MACHINE_SECRET_VALUE_MIN_LENGTH = 8;
49195
+ /**
49196
+ * Default VM runtime billing: charged to the chatting user's credits, prorated
49197
+ * per second. The rate is configurable per org, so the UI presents these as
49198
+ * the default rather than the org's actual rate.
49199
+ */
49200
+ const VIRTUAL_MACHINE_DEFAULT_BILLING = {
49201
+ usd: 1,
49202
+ minutes: 10,
49203
+ };
49204
+
49205
+ /**
49206
+ * Virtual Machine Shell network policies and secrets
49207
+ * (`/api/ai-account/orgs/{org}/virtual-machine-network-policy/` and
49208
+ * `/api/ai-account/orgs/{org}/virtual-machine-secret/`).
49209
+ *
49210
+ * Hand-written: these endpoints are newer than the pinned `@iblai/iblai-api`
49211
+ * release. Records are keyed in the body (PATCH) or the query string (DELETE),
49212
+ * never in the URL. A 403 on either list means the caller lacks the matching
49213
+ * `Ibl.Mentor/VirtualMachine…/list` permission — hosts hide the pages then.
49214
+ */
49215
+ const virtualMachineApiSlice = react.createApi({
49216
+ reducerPath: VIRTUAL_MACHINE_REDUCER_PATH,
49217
+ tagTypes: [VIRTUAL_MACHINE_QUERY_KEYS.NETWORK_POLICIES, VIRTUAL_MACHINE_QUERY_KEYS.SECRETS],
49218
+ baseQuery: iblFetchBaseQuery,
49219
+ endpoints: (builder) => ({
49220
+ // ── Network policies ────────────────────────────────────────────────
49221
+ listVirtualMachineNetworkPolicies: builder.query({
49222
+ query: ({ org }) => ({
49223
+ url: VIRTUAL_MACHINE_ENDPOINTS.NETWORK_POLICIES.path(org),
49224
+ service: VIRTUAL_MACHINE_ENDPOINTS.NETWORK_POLICIES.service,
49225
+ }),
49226
+ providesTags: [VIRTUAL_MACHINE_QUERY_KEYS.NETWORK_POLICIES],
49227
+ }),
49228
+ createVirtualMachineNetworkPolicy: builder.mutation({
49229
+ query: ({ org, body }) => ({
49230
+ url: VIRTUAL_MACHINE_ENDPOINTS.NETWORK_POLICIES.path(org),
49231
+ service: VIRTUAL_MACHINE_ENDPOINTS.NETWORK_POLICIES.service,
49232
+ method: 'POST',
49233
+ body,
49234
+ }),
49235
+ invalidatesTags: [VIRTUAL_MACHINE_QUERY_KEYS.NETWORK_POLICIES],
49236
+ }),
49237
+ // `body.id` names the policy; `allowed_hosts` replaces the whole list.
49238
+ updateVirtualMachineNetworkPolicy: builder.mutation({
49239
+ query: ({ org, body }) => ({
49240
+ url: VIRTUAL_MACHINE_ENDPOINTS.NETWORK_POLICIES.path(org),
49241
+ service: VIRTUAL_MACHINE_ENDPOINTS.NETWORK_POLICIES.service,
49242
+ method: 'PATCH',
49243
+ body,
49244
+ }),
49245
+ invalidatesTags: [VIRTUAL_MACHINE_QUERY_KEYS.NETWORK_POLICIES],
49246
+ }),
49247
+ // 400 when an agent still uses the policy — the message names the agents.
49248
+ deleteVirtualMachineNetworkPolicy: builder.mutation({
49249
+ query: ({ org, id }) => ({
49250
+ url: VIRTUAL_MACHINE_ENDPOINTS.NETWORK_POLICIES.path(org),
49251
+ service: VIRTUAL_MACHINE_ENDPOINTS.NETWORK_POLICIES.service,
49252
+ method: 'DELETE',
49253
+ params: { id },
49254
+ }),
49255
+ invalidatesTags: [VIRTUAL_MACHINE_QUERY_KEYS.NETWORK_POLICIES],
49256
+ }),
49257
+ // ── VM secrets ──────────────────────────────────────────────────────
49258
+ listVirtualMachineSecrets: builder.query({
49259
+ query: ({ org }) => ({
49260
+ url: VIRTUAL_MACHINE_ENDPOINTS.SECRETS.path(org),
49261
+ service: VIRTUAL_MACHINE_ENDPOINTS.SECRETS.service,
49262
+ }),
49263
+ providesTags: [VIRTUAL_MACHINE_QUERY_KEYS.SECRETS],
49264
+ }),
49265
+ // Either `value` or `source_credential_id` + `source_field`, never both.
49266
+ createVirtualMachineSecret: builder.mutation({
49267
+ query: ({ org, body }) => ({
49268
+ url: VIRTUAL_MACHINE_ENDPOINTS.SECRETS.path(org),
49269
+ service: VIRTUAL_MACHINE_ENDPOINTS.SECRETS.service,
49270
+ method: 'POST',
49271
+ body,
49272
+ }),
49273
+ invalidatesTags: [VIRTUAL_MACHINE_QUERY_KEYS.SECRETS],
49274
+ }),
49275
+ // `body.env_var` names the secret and cannot change.
49276
+ updateVirtualMachineSecret: builder.mutation({
49277
+ query: ({ org, body }) => ({
49278
+ url: VIRTUAL_MACHINE_ENDPOINTS.SECRETS.path(org),
49279
+ service: VIRTUAL_MACHINE_ENDPOINTS.SECRETS.service,
49280
+ method: 'PATCH',
49281
+ body,
49282
+ }),
49283
+ invalidatesTags: [VIRTUAL_MACHINE_QUERY_KEYS.SECRETS],
49284
+ }),
49285
+ // Also unbinds the secret from every agent that uses it.
49286
+ deleteVirtualMachineSecret: builder.mutation({
49287
+ query: ({ org, envVar }) => ({
49288
+ url: VIRTUAL_MACHINE_ENDPOINTS.SECRETS.path(org),
49289
+ service: VIRTUAL_MACHINE_ENDPOINTS.SECRETS.service,
49290
+ method: 'DELETE',
49291
+ params: { env_var: envVar },
49292
+ }),
49293
+ invalidatesTags: [VIRTUAL_MACHINE_QUERY_KEYS.SECRETS],
49294
+ }),
49295
+ }),
49296
+ });
49297
+ const { useListVirtualMachineNetworkPoliciesQuery, useLazyListVirtualMachineNetworkPoliciesQuery, useCreateVirtualMachineNetworkPolicyMutation, useUpdateVirtualMachineNetworkPolicyMutation, useDeleteVirtualMachineNetworkPolicyMutation, useListVirtualMachineSecretsQuery, useLazyListVirtualMachineSecretsQuery, useCreateVirtualMachineSecretMutation, useUpdateVirtualMachineSecretMutation, useDeleteVirtualMachineSecretMutation, } = virtualMachineApiSlice;
49298
+
49299
+ /**
49300
+ * Normalise a `host:port` entry the way the backend stores it: trimmed and
49301
+ * lowercased.
49302
+ */
49303
+ function normalizeHostPort(value) {
49304
+ return value.trim().toLowerCase();
49305
+ }
49306
+ /** Split a pasted or typed string into candidate `host:port` entries. */
49307
+ function splitHostPortInput(value) {
49308
+ return value
49309
+ .split(/[\s,;]+/)
49310
+ .map(normalizeHostPort)
49311
+ .filter((entry) => entry.length > 0);
49312
+ }
49313
+ const IPV4_PATTERN = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
49314
+ /** Whether the host part is an IPv4 literal (the `host:port` grammar admits no IPv6). */
49315
+ function isIpAddressHost(host) {
49316
+ return IPV4_PATTERN.test(host);
49317
+ }
49318
+ /**
49319
+ * IPv4 literals the backend refuses even where IPs are allowed: loopback,
49320
+ * link-local, multicast, reserved and the unspecified address.
49321
+ */
49322
+ function isRejectedIpAddress(host) {
49323
+ const match = IPV4_PATTERN.exec(host);
49324
+ if (!match)
49325
+ return false;
49326
+ const octets = match.slice(1, 5).map(Number);
49327
+ if (octets.some((octet) => octet > 255))
49328
+ return true;
49329
+ const [first, second] = octets;
49330
+ if (first === 0)
49331
+ return true; // unspecified / "this" network
49332
+ if (first === 127)
49333
+ return true; // loopback
49334
+ if (first === 169 && second === 254)
49335
+ return true; // link-local
49336
+ if (first >= 224)
49337
+ return true; // multicast (224–239) and reserved (240+)
49338
+ return false;
49339
+ }
49340
+ /** Whether the backend refuses this hostname outright (localhost, metadata, `.internal`, …). */
49341
+ function isRejectedHostname(host) {
49342
+ const lowered = host.toLowerCase();
49343
+ if (VIRTUAL_MACHINE_REJECTED_HOSTS.includes(lowered))
49344
+ return true;
49345
+ return VIRTUAL_MACHINE_REJECTED_HOST_SUFFIXES.some((suffix) => lowered.endsWith(suffix));
49346
+ }
49347
+ /**
49348
+ * Client-side check of one `host:port` entry, returning why it fails or `null`
49349
+ * when it looks valid. Network policies accept IP addresses; VM secrets do
49350
+ * not (`allowIpAddresses: false`, the default). The backend remains
49351
+ * authoritative, so always show its message when it rejects an entry.
49352
+ */
49353
+ function validateHostPort(value, options = {}) {
49354
+ const entry = normalizeHostPort(value);
49355
+ if (!VIRTUAL_MACHINE_HOST_PORT_PATTERN.test(entry))
49356
+ return 'format';
49357
+ const separator = entry.lastIndexOf(':');
49358
+ const host = entry.slice(0, separator);
49359
+ const port = Number(entry.slice(separator + 1));
49360
+ if (port < 1 || port > 65535)
49361
+ return 'port';
49362
+ if (isRejectedHostname(host))
49363
+ return 'rejected_host';
49364
+ if (isIpAddressHost(host)) {
49365
+ if (!options.allowIpAddresses)
49366
+ return 'ip_not_allowed';
49367
+ if (isRejectedIpAddress(host))
49368
+ return 'rejected_host';
49369
+ }
49370
+ return null;
49371
+ }
49372
+ /** Convenience wrapper around {@link validateHostPort}. */
49373
+ function isValidHostPort(value, options = {}) {
49374
+ return validateHostPort(value, options) === null;
49375
+ }
49376
+ /** HTTP status of an RTK Query error, if it carries one. */
49377
+ function getVirtualMachineErrorStatus(error) {
49378
+ const status = error === null || error === void 0 ? void 0 : error.status;
49379
+ return typeof status === 'number' ? status : undefined;
49380
+ }
49381
+ function toMessages(value) {
49382
+ if (typeof value === 'string')
49383
+ return [value];
49384
+ if (Array.isArray(value))
49385
+ return value.filter((item) => typeof item === 'string');
49386
+ return [];
49387
+ }
49388
+ /**
49389
+ * Normalise a virtual-machine endpoint error for display. Every 400 has the
49390
+ * form `{ error }`, where `error` is either a plain string (shown as a
49391
+ * form-level message) or an object of field → messages (shown next to the
49392
+ * matching field). `non_field_errors` is folded into the form-level message.
49393
+ * Other shapes (`detail`, a bare string body) fall back to a message too.
49394
+ */
49395
+ function getVirtualMachineApiError(error) {
49396
+ const status = getVirtualMachineErrorStatus(error);
49397
+ const data = error === null || error === void 0 ? void 0 : error.data;
49398
+ const fieldErrors = {};
49399
+ let message = null;
49400
+ if (typeof data === 'string') {
49401
+ message = data;
49402
+ }
49403
+ else if (data && typeof data === 'object') {
49404
+ const body = data;
49405
+ if (typeof body.error === 'string') {
49406
+ message = body.error;
49407
+ }
49408
+ else if (body.error && typeof body.error === 'object') {
49409
+ for (const [field, messages] of Object.entries(body.error)) {
49410
+ const list = toMessages(messages);
49411
+ if (list.length === 0)
49412
+ continue;
49413
+ if (field === 'non_field_errors') {
49414
+ message = list.join(' ');
49415
+ }
49416
+ else {
49417
+ fieldErrors[field] = list;
49418
+ }
49419
+ }
49420
+ }
49421
+ else if (typeof body.detail === 'string') {
49422
+ message = body.detail;
49423
+ }
49424
+ else if (typeof body.message === 'string') {
49425
+ message = body.message;
49426
+ }
49427
+ }
49428
+ return { status, message, fieldErrors };
49429
+ }
49430
+ /**
49431
+ * Agent ids named by the "bound to mentors" delete error, e.g.
49432
+ * `"This network policy is bound to mentors; move them off it first: ['<uuid>', '<uuid>']"`.
49433
+ */
49434
+ function extractBoundMentorIds(message) {
49435
+ if (!message)
49436
+ return [];
49437
+ const listStart = message.indexOf('[');
49438
+ const listEnd = message.lastIndexOf(']');
49439
+ if (listStart === -1 || listEnd <= listStart)
49440
+ return [];
49441
+ const ids = [];
49442
+ const quoted = /['"]([^'"]+)['"]/g;
49443
+ let match;
49444
+ const list = message.slice(listStart + 1, listEnd);
49445
+ while ((match = quoted.exec(list)) !== null) {
49446
+ ids.push(match[1]);
49447
+ }
49448
+ return ids;
49449
+ }
49450
+ /** Whether an egress profile lets the VM reach hosts at all (and so may carry secrets). */
49451
+ function isVirtualMachineEgressNetworked(egress) {
49452
+ return egress === 'public' || egress === 'custom';
49453
+ }
49454
+ /**
49455
+ * Under the `custom` profile every host a bound secret is sent to must be in
49456
+ * the network policy. Returns, per secret, the hosts the policy is missing.
49457
+ */
49458
+ function findUncoveredSecretHosts(secrets, allowedHosts) {
49459
+ const allowed = new Set(allowedHosts.map(normalizeHostPort));
49460
+ const uncovered = [];
49461
+ for (const secret of secrets) {
49462
+ const hosts = secret.allow_hosts.map(normalizeHostPort).filter((host) => !allowed.has(host));
49463
+ if (hosts.length > 0)
49464
+ uncovered.push({ envVar: secret.env_var, hosts });
49465
+ }
49466
+ return uncovered;
49467
+ }
49468
+
49118
49469
  const mentorReducer = {
49119
49470
  [mentorApiSlice.reducerPath]: mentorApiSlice.reducer,
49120
49471
  [tenantApiSlice.reducerPath]: tenantApiSlice.reducer,
@@ -49178,6 +49529,7 @@ const mentorReducer = {
49178
49529
  [gradingApiSlice.reducerPath]: gradingApiSlice.reducer,
49179
49530
  [spendCapsApiSlice.reducerPath]: spendCapsApiSlice.reducer,
49180
49531
  [userChatHistoryApiSlice.reducerPath]: userChatHistoryApiSlice.reducer,
49532
+ [virtualMachineApiSlice.reducerPath]: virtualMachineApiSlice.reducer,
49181
49533
  [userLlmUsageApiSlice.reducerPath]: userLlmUsageApiSlice.reducer,
49182
49534
  };
49183
49535
  const mentorMiddleware = [
@@ -49243,6 +49595,7 @@ const mentorMiddleware = [
49243
49595
  gradingApiSlice.middleware,
49244
49596
  spendCapsApiSlice.middleware,
49245
49597
  userChatHistoryApiSlice.middleware,
49598
+ virtualMachineApiSlice.middleware,
49246
49599
  userLlmUsageApiSlice.middleware,
49247
49600
  ];
49248
49601
 
@@ -49291,6 +49644,7 @@ const skillsReducer = {
49291
49644
  [chatPrivacyApiSlice.reducerPath]: chatPrivacyApiSlice.reducer,
49292
49645
  [agentSkillsApiSlice.reducerPath]: agentSkillsApiSlice.reducer,
49293
49646
  [userChatHistoryApiSlice.reducerPath]: userChatHistoryApiSlice.reducer,
49647
+ [virtualMachineApiSlice.reducerPath]: virtualMachineApiSlice.reducer,
49294
49648
  [chatApiSlice.reducerPath]: chatApiSlice.reducer,
49295
49649
  [userLlmUsageApiSlice.reducerPath]: userLlmUsageApiSlice.reducer,
49296
49650
  };
@@ -49339,6 +49693,7 @@ const skillsMiddleware = [
49339
49693
  chatPrivacyApiSlice.middleware,
49340
49694
  agentSkillsApiSlice.middleware,
49341
49695
  userChatHistoryApiSlice.middleware,
49696
+ virtualMachineApiSlice.middleware,
49342
49697
  chatApiSlice.middleware,
49343
49698
  userLlmUsageApiSlice.middleware,
49344
49699
  ];
@@ -49465,6 +49820,19 @@ exports.USER_LLM_USAGE_REDUCER_PATH = USER_LLM_USAGE_REDUCER_PATH;
49465
49820
  exports.USER_PROGRESS_DATA_POINTS = USER_PROGRESS_DATA_POINTS;
49466
49821
  exports.USER_PROGRESS_SUMMARY_TYPE = USER_PROGRESS_SUMMARY_TYPE;
49467
49822
  exports.VERCEL_SPA = VERCEL_SPA;
49823
+ exports.VIRTUAL_MACHINE_DEFAULT_BILLING = VIRTUAL_MACHINE_DEFAULT_BILLING;
49824
+ exports.VIRTUAL_MACHINE_EGRESS_PROFILES = VIRTUAL_MACHINE_EGRESS_PROFILES;
49825
+ exports.VIRTUAL_MACHINE_ENDPOINTS = VIRTUAL_MACHINE_ENDPOINTS;
49826
+ exports.VIRTUAL_MACHINE_ENV_VAR_PATTERN = VIRTUAL_MACHINE_ENV_VAR_PATTERN;
49827
+ exports.VIRTUAL_MACHINE_HOST_PORT_PATTERN = VIRTUAL_MACHINE_HOST_PORT_PATTERN;
49828
+ exports.VIRTUAL_MACHINE_MAX_POLICY_HOSTS = VIRTUAL_MACHINE_MAX_POLICY_HOSTS;
49829
+ exports.VIRTUAL_MACHINE_MAX_SECRETS_PER_MENTOR = VIRTUAL_MACHINE_MAX_SECRETS_PER_MENTOR;
49830
+ exports.VIRTUAL_MACHINE_PERMISSIONS = VIRTUAL_MACHINE_PERMISSIONS;
49831
+ exports.VIRTUAL_MACHINE_QUERY_KEYS = VIRTUAL_MACHINE_QUERY_KEYS;
49832
+ exports.VIRTUAL_MACHINE_REDUCER_PATH = VIRTUAL_MACHINE_REDUCER_PATH;
49833
+ exports.VIRTUAL_MACHINE_REJECTED_HOSTS = VIRTUAL_MACHINE_REJECTED_HOSTS;
49834
+ exports.VIRTUAL_MACHINE_REJECTED_HOST_SUFFIXES = VIRTUAL_MACHINE_REJECTED_HOST_SUFFIXES;
49835
+ exports.VIRTUAL_MACHINE_SECRET_VALUE_MIN_LENGTH = VIRTUAL_MACHINE_SECRET_VALUE_MIN_LENGTH;
49468
49836
  exports.WATCHED_GROUPS_ENDPOINTS = WATCHED_GROUPS_ENDPOINTS;
49469
49837
  exports.WATCHED_GROUPS_QUERY_KEYS = WATCHED_GROUPS_QUERY_KEYS;
49470
49838
  exports.WATCHED_GROUPS_REDUCER_PATH = WATCHED_GROUPS_REDUCER_PATH;
@@ -49516,6 +49884,7 @@ exports.edxProctoringApiSlice = edxProctoringApiSlice;
49516
49884
  exports.edxSsoApiSlice = edxSsoApiSlice;
49517
49885
  exports.evalTotalPages = evalTotalPages;
49518
49886
  exports.evaluationsApiSlice = evaluationsApiSlice;
49887
+ exports.extractBoundMentorIds = extractBoundMentorIds;
49519
49888
  exports.fakeBaseQueryWithLogging = fakeBaseQueryWithLogging;
49520
49889
  exports.featureTags = featureTags;
49521
49890
  exports.fetchLearnerCompletion = fetchLearnerCompletion;
@@ -49525,20 +49894,28 @@ exports.filterGlobalUserRoles = filterGlobalUserRoles;
49525
49894
  exports.filterOrgUserRoles = filterOrgUserRoles;
49526
49895
  exports.filterSlashSkills = filterSlashSkills;
49527
49896
  exports.findResumeBlock = findResumeBlock;
49897
+ exports.findUncoveredSecretHosts = findUncoveredSecretHosts;
49528
49898
  exports.flattenOutline = flattenOutline;
49529
49899
  exports.getNextRecentMessagesPageParam = getNextRecentMessagesPageParam;
49530
49900
  exports.getSections = getSections;
49531
49901
  exports.getSpendCapExceededError = getSpendCapExceededError;
49532
49902
  exports.getUserRoleScope = getUserRoleScope;
49903
+ exports.getVirtualMachineApiError = getVirtualMachineApiError;
49904
+ exports.getVirtualMachineErrorStatus = getVirtualMachineErrorStatus;
49533
49905
  exports.gradingApiSlice = gradingApiSlice;
49534
49906
  exports.hostingApiSlice = hostingApiSlice;
49535
49907
  exports.iblFakeBaseQuery = iblFakeBaseQuery;
49536
49908
  exports.initializeDataLayer = initializeDataLayer;
49537
49909
  exports.isBaseAgentMentor = isBaseAgentMentor;
49910
+ exports.isIpAddressHost = isIpAddressHost;
49538
49911
  exports.isPoliciesResponse = isPoliciesResponse;
49539
49912
  exports.isPrivacyBlockedError = isPrivacyBlockedError;
49913
+ exports.isRejectedHostname = isRejectedHostname;
49914
+ exports.isRejectedIpAddress = isRejectedIpAddress;
49540
49915
  exports.isSpendCapExceededErrorBody = isSpendCapExceededErrorBody;
49541
49916
  exports.isUserLlmUsageEmpty = isUserLlmUsageEmpty;
49917
+ exports.isValidHostPort = isValidHostPort;
49918
+ exports.isVirtualMachineEgressNetworked = isVirtualMachineEgressNetworked;
49542
49919
  exports.llmsApiSlice = llmsApiSlice;
49543
49920
  exports.mcpApiSlice = mcpApiSlice;
49544
49921
  exports.memoryApiSlice = memoryApiSlice;
@@ -49551,6 +49928,7 @@ exports.mentorReducer = mentorReducer;
49551
49928
  exports.moderationLogsApiReducer = moderationLogsApiReducer;
49552
49929
  exports.moderationLogsApiSlice = moderationLogsApiSlice;
49553
49930
  exports.monetizationApiSlice = monetizationApiSlice;
49931
+ exports.normalizeHostPort = normalizeHostPort;
49554
49932
  exports.normalizeLearnerCompletionError = normalizeLearnerCompletionError;
49555
49933
  exports.normalizeOutline = normalizeOutline;
49556
49934
  exports.normalizeUserLlmUsageError = normalizeUserLlmUsageError;
@@ -49573,6 +49951,7 @@ exports.skillsApiSlice = skillsApiSlice;
49573
49951
  exports.skillsMiddleware = skillsMiddleware;
49574
49952
  exports.skillsReducer = skillsReducer;
49575
49953
  exports.spendCapsApiSlice = spendCapsApiSlice;
49954
+ exports.splitHostPortInput = splitHostPortInput;
49576
49955
  exports.stripeApiSlice = stripeApiSlice;
49577
49956
  exports.studioAuthoringApiSlice = studioAuthoringApiSlice;
49578
49957
  exports.supportTicketsApiSlice = supportTicketsApiSlice;
@@ -49680,6 +50059,8 @@ exports.useCreateUserInstitutionMutation = useCreateUserInstitutionMutation;
49680
50059
  exports.useCreateUserInvitationMutation = useCreateUserInvitationMutation;
49681
50060
  exports.useCreateUserProjectMutation = useCreateUserProjectMutation;
49682
50061
  exports.useCreateUserResumeMutation = useCreateUserResumeMutation;
50062
+ exports.useCreateVirtualMachineNetworkPolicyMutation = useCreateVirtualMachineNetworkPolicyMutation;
50063
+ exports.useCreateVirtualMachineSecretMutation = useCreateVirtualMachineSecretMutation;
49683
50064
  exports.useCreateWatchedGroupMutation = useCreateWatchedGroupMutation;
49684
50065
  exports.useCreateWorkflowMutation = useCreateWorkflowMutation;
49685
50066
  exports.useDeactivateWorkflowMutation = useDeactivateWorkflowMutation;
@@ -49738,6 +50119,8 @@ exports.useDeleteUserEducationMutation = useDeleteUserEducationMutation;
49738
50119
  exports.useDeleteUserExperienceMutation = useDeleteUserExperienceMutation;
49739
50120
  exports.useDeleteUserProjectMutation = useDeleteUserProjectMutation;
49740
50121
  exports.useDeleteUserSpendCapMutation = useDeleteUserSpendCapMutation;
50122
+ exports.useDeleteVirtualMachineNetworkPolicyMutation = useDeleteVirtualMachineNetworkPolicyMutation;
50123
+ exports.useDeleteVirtualMachineSecretMutation = useDeleteVirtualMachineSecretMutation;
49741
50124
  exports.useDeleteWatchedGroupMutation = useDeleteWatchedGroupMutation;
49742
50125
  exports.useDeleteWatcherMutation = useDeleteWatcherMutation;
49743
50126
  exports.useDeleteWorkflowMutation = useDeleteWorkflowMutation;
@@ -50264,6 +50647,8 @@ exports.useLazyListOwnApplicationsQuery = useLazyListOwnApplicationsQuery;
50264
50647
  exports.useLazyListPaywallsQuery = useLazyListPaywallsQuery;
50265
50648
  exports.useLazyListPricesQuery = useLazyListPricesQuery;
50266
50649
  exports.useLazyListSubscribersQuery = useLazyListSubscribersQuery;
50650
+ exports.useLazyListVirtualMachineNetworkPoliciesQuery = useLazyListVirtualMachineNetworkPoliciesQuery;
50651
+ exports.useLazyListVirtualMachineSecretsQuery = useLazyListVirtualMachineSecretsQuery;
50267
50652
  exports.useLazyPlatformUserGroupsQuery = useLazyPlatformUserGroupsQuery;
50268
50653
  exports.useLazyPlatformUsersQuery = useLazyPlatformUsersQuery;
50269
50654
  exports.useLazyRefreshJwtTokenQuery = useLazyRefreshJwtTokenQuery;
@@ -50289,6 +50674,8 @@ exports.useListOwnApplicationsQuery = useListOwnApplicationsQuery;
50289
50674
  exports.useListPaywallsQuery = useListPaywallsQuery;
50290
50675
  exports.useListPricesQuery = useListPricesQuery;
50291
50676
  exports.useListSubscribersQuery = useListSubscribersQuery;
50677
+ exports.useListVirtualMachineNetworkPoliciesQuery = useListVirtualMachineNetworkPoliciesQuery;
50678
+ exports.useListVirtualMachineSecretsQuery = useListVirtualMachineSecretsQuery;
50292
50679
  exports.useMarkAllAsReadMutation = useMarkAllAsReadMutation;
50293
50680
  exports.useOauthFindMutation = useOauthFindMutation;
50294
50681
  exports.useOverrideGradeResultMutation = useOverrideGradeResultMutation;
@@ -50405,6 +50792,8 @@ exports.useUpdateUserProjectMutation = useUpdateUserProjectMutation;
50405
50792
  exports.useUpdateUserRoleMutation = useUpdateUserRoleMutation;
50406
50793
  exports.useUpdateUserStatusMutation = useUpdateUserStatusMutation;
50407
50794
  exports.useUpdateUserTrialStatusMutation = useUpdateUserTrialStatusMutation;
50795
+ exports.useUpdateVirtualMachineNetworkPolicyMutation = useUpdateVirtualMachineNetworkPolicyMutation;
50796
+ exports.useUpdateVirtualMachineSecretMutation = useUpdateVirtualMachineSecretMutation;
50408
50797
  exports.useUpdateWatchedGroupMutation = useUpdateWatchedGroupMutation;
50409
50798
  exports.useUpdateWatcherMutation = useUpdateWatcherMutation;
50410
50799
  exports.useUpdateWorkflowMutation = useUpdateWorkflowMutation;
@@ -50437,8 +50826,10 @@ exports.userApiSlice = userApiSlice;
50437
50826
  exports.userChatHistoryApiSlice = userChatHistoryApiSlice;
50438
50827
  exports.userInvitationsApiSlice = userInvitationsApiSlice;
50439
50828
  exports.userLlmUsageApiSlice = userLlmUsageApiSlice;
50829
+ exports.validateHostPort = validateHostPort;
50440
50830
  exports.validateLearnerCompletionArgs = validateLearnerCompletionArgs;
50441
50831
  exports.validateUserLlmUsageParams = validateUserLlmUsageParams;
50832
+ exports.virtualMachineApiSlice = virtualMachineApiSlice;
50442
50833
  exports.watchedGroupsApiSlice = watchedGroupsApiSlice;
50443
50834
  exports.workflowsApiSlice = workflowsApiSlice;
50444
50835
  //# sourceMappingURL=index.js.map