@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.
@@ -0,0 +1,63 @@
1
+ import { SERVICES } from '@data-layer/constants';
2
+ export declare const VIRTUAL_MACHINE_REDUCER_PATH = "virtualMachineApiSlice";
3
+ export declare const VIRTUAL_MACHINE_QUERY_KEYS: {
4
+ readonly NETWORK_POLICIES: "VirtualMachineNetworkPolicies";
5
+ readonly SECRETS: "VirtualMachineSecrets";
6
+ };
7
+ export declare const VIRTUAL_MACHINE_ENDPOINTS: {
8
+ /** GET (list) / POST (create) / PATCH (update by `id`) / DELETE (by `id`). */
9
+ NETWORK_POLICIES: {
10
+ service: SERVICES;
11
+ path: (org: string) => string;
12
+ };
13
+ /** GET (list) / POST (create) / PATCH (update by `env_var`) / DELETE (by `env_var`). */
14
+ SECRETS: {
15
+ service: SERVICES;
16
+ path: (org: string) => string;
17
+ };
18
+ };
19
+ /**
20
+ * RBAC permission names the backend checks on each endpoint. Listed for
21
+ * reference — the UI gates on the list call's 403 rather than on these.
22
+ */
23
+ export declare const VIRTUAL_MACHINE_PERMISSIONS: {
24
+ readonly NETWORK_POLICIES: {
25
+ readonly LIST: "Ibl.Mentor/VirtualMachineNetworkPolicies/list";
26
+ readonly WRITE: "Ibl.Mentor/VirtualMachineNetworkPolicies/write";
27
+ readonly DELETE: "Ibl.Mentor/VirtualMachineNetworkPolicies/delete";
28
+ };
29
+ readonly SECRETS: {
30
+ readonly LIST: "Ibl.Mentor/VirtualMachineSecrets/list";
31
+ readonly WRITE: "Ibl.Mentor/VirtualMachineSecrets/write";
32
+ readonly DELETE: "Ibl.Mentor/VirtualMachineSecrets/delete";
33
+ };
34
+ };
35
+ /** Egress profiles, in the order the UI lists them. `none` is the default. */
36
+ export declare const VIRTUAL_MACHINE_EGRESS_PROFILES: readonly ["none", "registries", "public", "custom"];
37
+ /**
38
+ * Fast client-side check for a `host:port` entry. The backend is authoritative
39
+ * (it also rejects wildcards, schemes, paths and the reserved hosts below), so
40
+ * its message is always surfaced when it disagrees.
41
+ */
42
+ export declare const VIRTUAL_MACHINE_HOST_PORT_PATTERN: RegExp;
43
+ /** Hostnames the backend refuses in any allowlist. */
44
+ export declare const VIRTUAL_MACHINE_REJECTED_HOSTS: readonly ["localhost", "metadata", "metadata.google.internal", "instance-data", "instance-data.ec2.internal"];
45
+ /** Hostname suffixes the backend refuses in any allowlist. */
46
+ export declare const VIRTUAL_MACHINE_REJECTED_HOST_SUFFIXES: readonly [".local", ".internal", ".localhost"];
47
+ /** `env_var` of a VM secret: a POSIX-style environment variable name. */
48
+ export declare const VIRTUAL_MACHINE_ENV_VAR_PATTERN: RegExp;
49
+ /** A network policy holds between 1 and 100 hosts. */
50
+ export declare const VIRTUAL_MACHINE_MAX_POLICY_HOSTS = 100;
51
+ /** An agent may bind at most 20 VM secrets. */
52
+ export declare const VIRTUAL_MACHINE_MAX_SECRETS_PER_MENTOR = 20;
53
+ /** A pasted secret value must be at least this long. */
54
+ export declare const VIRTUAL_MACHINE_SECRET_VALUE_MIN_LENGTH = 8;
55
+ /**
56
+ * Default VM runtime billing: charged to the chatting user's credits, prorated
57
+ * per second. The rate is configurable per org, so the UI presents these as
58
+ * the default rather than the org's actual rate.
59
+ */
60
+ export declare const VIRTUAL_MACHINE_DEFAULT_BILLING: {
61
+ readonly usd: 1;
62
+ readonly minutes: 10;
63
+ };
@@ -0,0 +1,4 @@
1
+ export * from './api-slice';
2
+ export * from './constants';
3
+ export * from './types';
4
+ export * from './utils';
@@ -0,0 +1,163 @@
1
+ import { VIRTUAL_MACHINE_EGRESS_PROFILES } from './constants';
2
+ /**
3
+ * How much network the agent's VM gets:
4
+ * - `none` — nothing (default)
5
+ * - `registries` — PyPI, npm, apt and apk only
6
+ * - `public` — any public host; private networks, localhost and cloud metadata stay blocked
7
+ * - `custom` — only the hosts in the bound network policy
8
+ */
9
+ export type VirtualMachineEgress = (typeof VIRTUAL_MACHINE_EGRESS_PROFILES)[number];
10
+ export interface VirtualMachineNetworkPolicy {
11
+ id: number;
12
+ /** Unique within the org, max 255 characters. */
13
+ name: string;
14
+ /** 1–100 `host:port` entries. IP addresses are allowed (except reserved ranges). */
15
+ allowed_hosts: string[];
16
+ /** May be blank. */
17
+ description: string;
18
+ created_at: string;
19
+ updated_at: string;
20
+ }
21
+ export interface VirtualMachineNetworkPolicyCreateRequest {
22
+ name: string;
23
+ allowed_hosts: string[];
24
+ description?: string;
25
+ }
26
+ /** `id` identifies the policy; send only the fields that change. `allowed_hosts` replaces the whole list. */
27
+ export interface VirtualMachineNetworkPolicyUpdateRequest {
28
+ id: number;
29
+ name?: string;
30
+ allowed_hosts?: string[];
31
+ description?: string;
32
+ }
33
+ export interface ListVirtualMachineNetworkPoliciesArgs {
34
+ org: string;
35
+ }
36
+ export interface CreateVirtualMachineNetworkPolicyArgs {
37
+ org: string;
38
+ body: VirtualMachineNetworkPolicyCreateRequest;
39
+ }
40
+ export interface UpdateVirtualMachineNetworkPolicyArgs {
41
+ org: string;
42
+ body: VirtualMachineNetworkPolicyUpdateRequest;
43
+ }
44
+ export interface DeleteVirtualMachineNetworkPolicyArgs {
45
+ org: string;
46
+ id: number;
47
+ }
48
+ /**
49
+ * A secret as the list endpoint returns it. No endpoint ever returns the
50
+ * value, not even masked.
51
+ */
52
+ export interface VirtualMachineSecret {
53
+ /** Used when binding the secret to an agent. */
54
+ id: number;
55
+ /** Display name, max 255 characters. */
56
+ name: string;
57
+ /**
58
+ * The environment variable the agent uses (e.g. `ACME_KEY`). Unique within
59
+ * the org and the key for PATCH and DELETE; it cannot be renamed.
60
+ */
61
+ env_var: string;
62
+ /** The only hosts the real value is ever sent to. Hostnames only, no IPs. */
63
+ allow_hosts: string[];
64
+ /** Set when the value is read from an integration credential at run time. */
65
+ source_credential_id: number | null;
66
+ /** The credential field the value is read from; `""` for a stored value. */
67
+ source_field: string;
68
+ created_at: string;
69
+ updated_at: string;
70
+ }
71
+ /**
72
+ * Create with **either** `value` (a pasted key, min 8 characters) **or**
73
+ * `source_credential_id` + `source_field` (read from an integration
74
+ * credential at run time), never both.
75
+ */
76
+ export interface VirtualMachineSecretCreateRequest {
77
+ name: string;
78
+ env_var: string;
79
+ allow_hosts: string[];
80
+ value?: string;
81
+ source_credential_id?: number;
82
+ source_field?: string;
83
+ }
84
+ /**
85
+ * `env_var` identifies the secret; send only the fields that change. Sending
86
+ * `value` switches it to a stored value and drops any credential link; sending
87
+ * `source_credential_id` + `source_field` switches it to a credential and
88
+ * discards the stored value; sending neither leaves the value unchanged.
89
+ */
90
+ export interface VirtualMachineSecretUpdateRequest {
91
+ env_var: string;
92
+ name?: string;
93
+ allow_hosts?: string[];
94
+ value?: string;
95
+ source_credential_id?: number;
96
+ source_field?: string;
97
+ }
98
+ export interface ListVirtualMachineSecretsArgs {
99
+ org: string;
100
+ }
101
+ export interface CreateVirtualMachineSecretArgs {
102
+ org: string;
103
+ body: VirtualMachineSecretCreateRequest;
104
+ }
105
+ export interface UpdateVirtualMachineSecretArgs {
106
+ org: string;
107
+ body: VirtualMachineSecretUpdateRequest;
108
+ }
109
+ export interface DeleteVirtualMachineSecretArgs {
110
+ org: string;
111
+ envVar: string;
112
+ }
113
+ /** The bound policy as embedded in the mentor-settings response. */
114
+ export interface MentorVirtualMachineNetworkPolicyRef {
115
+ id: number;
116
+ name: string;
117
+ allowed_hosts: string[];
118
+ }
119
+ /** A bound secret as embedded in the mentor-settings response. */
120
+ export interface MentorVirtualMachineSecretRef {
121
+ id: number;
122
+ name: string;
123
+ env_var: string;
124
+ allow_hosts: string[];
125
+ source_credential_id: number | null;
126
+ }
127
+ export interface MentorVirtualMachineSettings {
128
+ enable_virtual_machine: boolean;
129
+ virtual_machine_egress: VirtualMachineEgress;
130
+ /** `null` when no policy is bound. */
131
+ virtual_machine_network_policy: MentorVirtualMachineNetworkPolicyRef | null;
132
+ /** `[]` when no secrets are bound. */
133
+ virtual_machine_secrets: MentorVirtualMachineSecretRef[];
134
+ }
135
+ /** PUT keys — the endpoint is a partial update, so send only what changes. */
136
+ export interface MentorVirtualMachineSettingsUpdate {
137
+ enable_virtual_machine?: boolean;
138
+ virtual_machine_egress?: VirtualMachineEgress;
139
+ /** The policy used under `custom`; `null` clears it. */
140
+ virtual_machine_network_policy_id?: number | null;
141
+ /** Replaces the full set of bound secrets; `[]` unbinds all. Max 20. */
142
+ virtual_machine_secret_ids?: number[];
143
+ }
144
+ /** Field → messages, e.g. `{ allowed_hosts: ["'x' must be 'host:port'…"] }`. */
145
+ export type VirtualMachineApiFieldErrors = Record<string, string[]>;
146
+ /** Every 400 from these endpoints: `error` is either field errors or a plain message. */
147
+ export interface VirtualMachineApiErrorBody {
148
+ error: string | VirtualMachineApiFieldErrors;
149
+ }
150
+ /** A 400 body normalised for display: a form-level message and/or per-field messages. */
151
+ export interface VirtualMachineApiError {
152
+ status?: number;
153
+ /** Form-level message (a plain-string `error`, or `non_field_errors`). */
154
+ message: string | null;
155
+ fieldErrors: VirtualMachineApiFieldErrors;
156
+ }
157
+ /** Why a `host:port` entry failed the client-side check. */
158
+ export type VirtualMachineHostPortIssue = 'format' | 'port' | 'rejected_host' | 'ip_not_allowed';
159
+ /** Hosts a bound secret needs that the bound network policy does not allow. */
160
+ export interface VirtualMachineUncoveredSecretHosts {
161
+ envVar: string;
162
+ hosts: string[];
163
+ }
@@ -0,0 +1,55 @@
1
+ import type { VirtualMachineApiError, VirtualMachineEgress, VirtualMachineHostPortIssue, VirtualMachineUncoveredSecretHosts } from './types';
2
+ /**
3
+ * Normalise a `host:port` entry the way the backend stores it: trimmed and
4
+ * lowercased.
5
+ */
6
+ export declare function normalizeHostPort(value: string): string;
7
+ /** Split a pasted or typed string into candidate `host:port` entries. */
8
+ export declare function splitHostPortInput(value: string): string[];
9
+ /** Whether the host part is an IPv4 literal (the `host:port` grammar admits no IPv6). */
10
+ export declare function isIpAddressHost(host: string): boolean;
11
+ /**
12
+ * IPv4 literals the backend refuses even where IPs are allowed: loopback,
13
+ * link-local, multicast, reserved and the unspecified address.
14
+ */
15
+ export declare function isRejectedIpAddress(host: string): boolean;
16
+ /** Whether the backend refuses this hostname outright (localhost, metadata, `.internal`, …). */
17
+ export declare function isRejectedHostname(host: string): boolean;
18
+ /**
19
+ * Client-side check of one `host:port` entry, returning why it fails or `null`
20
+ * when it looks valid. Network policies accept IP addresses; VM secrets do
21
+ * not (`allowIpAddresses: false`, the default). The backend remains
22
+ * authoritative, so always show its message when it rejects an entry.
23
+ */
24
+ export declare function validateHostPort(value: string, options?: {
25
+ allowIpAddresses?: boolean;
26
+ }): VirtualMachineHostPortIssue | null;
27
+ /** Convenience wrapper around {@link validateHostPort}. */
28
+ export declare function isValidHostPort(value: string, options?: {
29
+ allowIpAddresses?: boolean;
30
+ }): boolean;
31
+ /** HTTP status of an RTK Query error, if it carries one. */
32
+ export declare function getVirtualMachineErrorStatus(error: unknown): number | undefined;
33
+ /**
34
+ * Normalise a virtual-machine endpoint error for display. Every 400 has the
35
+ * form `{ error }`, where `error` is either a plain string (shown as a
36
+ * form-level message) or an object of field → messages (shown next to the
37
+ * matching field). `non_field_errors` is folded into the form-level message.
38
+ * Other shapes (`detail`, a bare string body) fall back to a message too.
39
+ */
40
+ export declare function getVirtualMachineApiError(error: unknown): VirtualMachineApiError;
41
+ /**
42
+ * Agent ids named by the "bound to mentors" delete error, e.g.
43
+ * `"This network policy is bound to mentors; move them off it first: ['<uuid>', '<uuid>']"`.
44
+ */
45
+ export declare function extractBoundMentorIds(message: string | null | undefined): string[];
46
+ /** Whether an egress profile lets the VM reach hosts at all (and so may carry secrets). */
47
+ export declare function isVirtualMachineEgressNetworked(egress: VirtualMachineEgress | undefined): boolean;
48
+ /**
49
+ * Under the `custom` profile every host a bound secret is sent to must be in
50
+ * the network policy. Returns, per secret, the hosts the policy is missing.
51
+ */
52
+ export declare function findUncoveredSecretHosts(secrets: ReadonlyArray<{
53
+ env_var: string;
54
+ allow_hosts: string[];
55
+ }>, allowedHosts: ReadonlyArray<string>): VirtualMachineUncoveredSecretHosts[];
@@ -148,6 +148,10 @@ export * from './features/user-llm-usage/constants';
148
148
  export * from './features/user-llm-usage/types';
149
149
  export * from './features/user-llm-usage/utils';
150
150
  export * from './features/user-llm-usage/hooks';
151
+ export * from './features/virtual-machine/api-slice';
152
+ export * from './features/virtual-machine/constants';
153
+ export * from './features/virtual-machine/types';
154
+ export * from './features/virtual-machine/utils';
151
155
  export * from './reducers';
152
156
  export * from './utils';
153
157
  export type { CustomQueryArgs } from './features/utils';