@ludeo/cloud-common 1.2.258-ygbeta1 → 1.2.258

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 (105) hide show
  1. package/.github/workflows/pr-check.yml +9 -0
  2. package/dist/tsconfig.tsbuildinfo +1 -1
  3. package/dist/v4/contexts/cloud-session-context.d.ts +1 -0
  4. package/dist/v4/contexts/cloud-session-context.js +5 -0
  5. package/dist/v4/contexts/cloud-session-context.js.map +1 -1
  6. package/dist/v4/events/build-assignment-settings-ready.d.ts +2 -0
  7. package/dist/v4/events/build-assignment-settings-ready.js +5 -0
  8. package/dist/v4/events/build-assignment-settings-ready.js.map +1 -1
  9. package/dist/v4/events/cloud-sessions/cloud-session-preempted.d.ts +20 -0
  10. package/dist/v4/events/cloud-sessions/cloud-session-preempted.js +74 -0
  11. package/dist/v4/events/cloud-sessions/cloud-session-preempted.js.map +1 -0
  12. package/dist/v4/events/cloud-sessions/index.d.ts +1 -0
  13. package/dist/v4/events/cloud-sessions/index.js +18 -0
  14. package/dist/v4/events/cloud-sessions/index.js.map +1 -0
  15. package/dist/v4/events/create-game-resource-request.d.ts +1 -0
  16. package/dist/v4/events/create-game-resource-request.js +5 -0
  17. package/dist/v4/events/create-game-resource-request.js.map +1 -1
  18. package/dist/v4/events/export-ludeocast-logs-request.d.ts +1 -0
  19. package/dist/v4/events/export-ludeocast-logs-request.js +4 -0
  20. package/dist/v4/events/export-ludeocast-logs-request.js.map +1 -1
  21. package/dist/v4/events/gameplay-waiting-for-user.d.ts +1 -1
  22. package/dist/v4/events/gameplay-waiting-for-user.js +1 -0
  23. package/dist/v4/events/gameplay-waiting-for-user.js.map +1 -1
  24. package/dist/v4/events/index.d.ts +1 -0
  25. package/dist/v4/events/index.js +2 -1
  26. package/dist/v4/events/index.js.map +1 -1
  27. package/dist/v4/events/ludeocast-agent/resource-update.js.map +1 -1
  28. package/dist/v4/events/provisioner/provisioning-ended.d.ts +2 -0
  29. package/dist/v4/events/provisioner/provisioning-ended.js +5 -0
  30. package/dist/v4/events/provisioner/provisioning-ended.js.map +1 -1
  31. package/dist/v4/events/site-controller/machine-ludeocast-preempted.d.ts +2 -0
  32. package/dist/v4/events/site-controller/machine-ludeocast-preempted.js +10 -0
  33. package/dist/v4/events/site-controller/machine-ludeocast-preempted.js.map +1 -1
  34. package/dist/v4/events/swap-cloud-user-gameplay-request-failed.d.ts +2 -2
  35. package/dist/v4/events/swap-cloud-user-gameplay-request-failed.js +2 -0
  36. package/dist/v4/events/swap-cloud-user-gameplay-request-failed.js.map +1 -1
  37. package/dist/v4/events/swap-cloud-user-gameplay-request.d.ts +2 -2
  38. package/dist/v4/events/swap-cloud-user-gameplay-request.js +2 -0
  39. package/dist/v4/events/swap-cloud-user-gameplay-request.js.map +1 -1
  40. package/dist/v4/events/swap-cloud-user-request-failed.d.ts +1 -1
  41. package/dist/v4/events/swap-cloud-user-request-failed.js +1 -0
  42. package/dist/v4/events/swap-cloud-user-request-failed.js.map +1 -1
  43. package/dist/v4/events/swap-cloud-user-request.d.ts +1 -1
  44. package/dist/v4/events/swap-cloud-user-request.js +1 -0
  45. package/dist/v4/events/swap-cloud-user-request.js.map +1 -1
  46. package/dist/v4/events/swap-to-default-user-completed.d.ts +1 -1
  47. package/dist/v4/events/swap-to-default-user-completed.js +1 -0
  48. package/dist/v4/events/swap-to-default-user-completed.js.map +1 -1
  49. package/dist/v4/events/swap-to-default-user-request-failed.d.ts +1 -1
  50. package/dist/v4/events/swap-to-default-user-request-failed.js +1 -0
  51. package/dist/v4/events/swap-to-default-user-request-failed.js.map +1 -1
  52. package/dist/v4/events/swap-to-default-user.d.ts +1 -1
  53. package/dist/v4/events/swap-to-default-user.js +1 -0
  54. package/dist/v4/events/swap-to-default-user.js.map +1 -1
  55. package/dist/v4/types/build.d.ts +1 -0
  56. package/dist/v4/types/build.js +5 -0
  57. package/dist/v4/types/build.js.map +1 -1
  58. package/dist/v4/types/cloud/cloud-configuration-settings.d.ts +12 -1
  59. package/dist/v4/types/cloud/cloud-configuration-settings.js +24 -6
  60. package/dist/v4/types/cloud/cloud-configuration-settings.js.map +1 -1
  61. package/dist/v4/types/cloud/cloud-configuration-settings.spec.d.ts +1 -0
  62. package/dist/v4/types/cloud/cloud-configuration-settings.spec.js +12 -0
  63. package/dist/v4/types/cloud/cloud-configuration-settings.spec.js.map +1 -0
  64. package/dist/v4/types/cloud/ludeocast-v2/gpu-type.d.ts +16 -0
  65. package/dist/v4/types/cloud/ludeocast-v2/gpu-type.js +54 -0
  66. package/dist/v4/types/cloud/ludeocast-v2/gpu-type.js.map +1 -0
  67. package/dist/v4/types/cloud/ludeocast-v2/index.d.ts +2 -0
  68. package/dist/v4/types/cloud/ludeocast-v2/index.js +2 -0
  69. package/dist/v4/types/cloud/ludeocast-v2/index.js.map +1 -1
  70. package/dist/v4/types/cloud/ludeocast-v2/machine-class.d.ts +7 -1
  71. package/dist/v4/types/cloud/ludeocast-v2/machine-class.js +6 -0
  72. package/dist/v4/types/cloud/ludeocast-v2/machine-class.js.map +1 -1
  73. package/dist/v4/types/cloud/ludeocast-v2/machine-resource-meta.d.ts +3 -0
  74. package/dist/v4/types/cloud/ludeocast-v2/machine-resource-meta.js +3 -0
  75. package/dist/v4/types/cloud/ludeocast-v2/machine-resource-meta.js.map +1 -0
  76. package/dist/v4/types/site-controller/types.d.ts +6 -0
  77. package/dist/v4/types/site-controller/types.js +25 -2
  78. package/dist/v4/types/site-controller/types.js.map +1 -1
  79. package/package.json +1 -1
  80. package/src/v4/contexts/cloud-session-context.ts +4 -0
  81. package/src/v4/events/build-assignment-settings-ready.ts +4 -0
  82. package/src/v4/events/cloud-sessions/cloud-session-preempted.ts +50 -0
  83. package/src/v4/events/cloud-sessions/index.ts +1 -0
  84. package/src/v4/events/create-game-resource-request.ts +4 -0
  85. package/src/v4/events/export-ludeocast-logs-request.ts +3 -0
  86. package/src/v4/events/gameplay-waiting-for-user.ts +2 -1
  87. package/src/v4/events/index.ts +1 -0
  88. package/src/v4/events/ludeocast-agent/resource-update.ts +4 -0
  89. package/src/v4/events/provisioner/provisioning-ended.ts +9 -1
  90. package/src/v4/events/site-controller/machine-ludeocast-preempted.ts +8 -0
  91. package/src/v4/events/swap-cloud-user-gameplay-request-failed.ts +5 -3
  92. package/src/v4/events/swap-cloud-user-gameplay-request.ts +4 -2
  93. package/src/v4/events/swap-cloud-user-request-failed.ts +2 -1
  94. package/src/v4/events/swap-cloud-user-request.ts +2 -1
  95. package/src/v4/events/swap-to-default-user-completed.ts +2 -1
  96. package/src/v4/events/swap-to-default-user-request-failed.ts +2 -1
  97. package/src/v4/events/swap-to-default-user.ts +2 -1
  98. package/src/v4/types/build.ts +4 -0
  99. package/src/v4/types/cloud/cloud-configuration-settings.spec.ts +12 -0
  100. package/src/v4/types/cloud/cloud-configuration-settings.ts +35 -10
  101. package/src/v4/types/cloud/ludeocast-v2/gpu-type.ts +57 -0
  102. package/src/v4/types/cloud/ludeocast-v2/index.ts +2 -0
  103. package/src/v4/types/cloud/ludeocast-v2/machine-class.ts +6 -0
  104. package/src/v4/types/cloud/ludeocast-v2/machine-resource-meta.ts +10 -0
  105. package/src/v4/types/site-controller/types.ts +22 -2
@@ -1,4 +1,4 @@
1
- import { IsString, IsUUID } from "class-validator";
1
+ import { IsOptional, IsString, IsUUID } from "class-validator";
2
2
 
3
3
  import { CloudSessionContext } from "../contexts";
4
4
  import { LudeoEvent } from "../../infra/ludeo-event";
@@ -17,11 +17,13 @@ export class SwapCloudUserGameplayRequestFailedPayload {
17
17
  @IsString()
18
18
  errorMessage: string;
19
19
 
20
+ @IsOptional()
20
21
  @IsUUID()
21
- ludeoResourceId: string;
22
+ ludeoResourceId?: string;
22
23
 
24
+ @IsOptional()
23
25
  @IsUUID()
24
- cloudSessionId: string;
26
+ cloudSessionId?: string;
25
27
  }
26
28
 
27
29
  export class SwapCloudUserGameplayRequestFailed extends LudeoEvent {
@@ -15,11 +15,13 @@ export class SwapCloudUserGameplayRequestPayload {
15
15
  @IsUUID()
16
16
  gameplayId: string;
17
17
 
18
+ @IsOptional()
18
19
  @IsUUID()
19
- ludeoResourceId: string;
20
+ ludeoResourceId?: string;
20
21
 
22
+ @IsOptional()
21
23
  @IsUUID()
22
- cloudSessionId: string;
24
+ cloudSessionId?: string;
23
25
 
24
26
  @IsString()
25
27
  actualUserSessionToken: string;
@@ -15,8 +15,9 @@ export class SwapCloudUserRequestFailedPayload {
15
15
  @IsOptional()
16
16
  actualUserSessionToken?: string;
17
17
 
18
+ @IsOptional()
18
19
  @IsUUID()
19
- ludeoResourceId: string;
20
+ ludeoResourceId?: string;
20
21
 
21
22
  @IsString()
22
23
  errorMessage: string;
@@ -16,8 +16,9 @@ export class SwapCloudUserRequestPayload {
16
16
  @IsString()
17
17
  actualUserSessionToken?: string;
18
18
 
19
+ @IsOptional()
19
20
  @IsUUID()
20
- ludeoResourceId: string;
21
+ ludeoResourceId?: string;
21
22
 
22
23
  @IsOptional()
23
24
  @IsEnum(CloudProvider)
@@ -5,8 +5,9 @@ import { CloudResourceContext } from "../contexts";
5
5
  import { IsUUIDOrEmpty } from "../../decorators/is-uuid-or-empty.decorator";
6
6
 
7
7
  export class SwapToDefaultUserCompletedPayload {
8
+ @IsOptional()
8
9
  @IsUUID()
9
- ludeoResourceId: string;
10
+ ludeoResourceId?: string;
10
11
 
11
12
  @IsUUID()
12
13
  connectionId: string;
@@ -5,8 +5,9 @@ import { ValidateNestedType } from "../../decorators/validate-nested-type.decora
5
5
  import { CloudResourceContext } from "../contexts";
6
6
 
7
7
  export class SwapToDefaultUserRequestFailedPayload {
8
+ @IsOptional()
8
9
  @IsUUID()
9
- ludeoResourceId: string;
10
+ ludeoResourceId?: string;
10
11
 
11
12
  @IsOptional()
12
13
  @IsUUID()
@@ -5,8 +5,9 @@ import { CloudResourceContext } from "../contexts";
5
5
  import { IsUUIDOrEmpty } from "../../decorators/is-uuid-or-empty.decorator";
6
6
 
7
7
  export class SwapToDefaultUserPayload {
8
+ @IsOptional()
8
9
  @IsUUID()
9
- ludeoResourceId: string;
10
+ ludeoResourceId?: string;
10
11
 
11
12
  @IsUUID()
12
13
  connectionId: string;
@@ -204,6 +204,10 @@ export class BuildVersionMeta {
204
204
 
205
205
  @IsString()
206
206
  buildVersion: string;
207
+
208
+ @IsOptional()
209
+ @IsString()
210
+ gameVersionId?: string;
207
211
  }
208
212
 
209
213
  export class RolloutConfig {
@@ -0,0 +1,12 @@
1
+ import type { CloudSettings } from "./cloud-configuration-settings";
2
+ import { CloudSettingsKeys, getCloudSettingsByKey } from "./cloud-configuration-settings";
3
+
4
+ describe("getCloudSettingsByKey", () => {
5
+ it("preserves SPOT_ROLLOUT 0 instead of falling back to default (100)", () => {
6
+ const settings = {
7
+ [CloudSettingsKeys.SPOT_ROLLOUT]: 0,
8
+ } as CloudSettings;
9
+
10
+ expect(getCloudSettingsByKey(CloudSettingsKeys.SPOT_ROLLOUT, settings)).toBe(0);
11
+ });
12
+ });
@@ -1,5 +1,11 @@
1
1
  import { LudeoCastV2MachineClass } from "./ludeocast-v2";
2
2
 
3
+ /** Stored values match UI labels for persistence and APIs. */
4
+ export enum CloudScalingMode {
5
+ MARKETING = "Marketing",
6
+ AUTO_SCALING = "Auto Scaling",
7
+ }
8
+
3
9
  export enum CloudSettingsKeys {
4
10
  GAME_LOADING_TIME = "gameLoadingTime",
5
11
  FIRST_TIME_LUDEO_LOAD = "firstTimeLudeoLoad",
@@ -9,6 +15,7 @@ export enum CloudSettingsKeys {
9
15
  ADDITIONAL_ENVIRONMENT_VARIABLES = "additionalEnvironmentVariables",
10
16
  MACHINE_CLASS_PRIORITY = "machineClassPriority",
11
17
  SPOT_ROLLOUT = "spotRollout",
18
+ SCALING = "scaling",
12
19
  }
13
20
 
14
21
  // Define the mapping of setting keys to their actual value types
@@ -21,18 +28,25 @@ export interface CloudSettingsTypeMap {
21
28
  [CloudSettingsKeys.ADDITIONAL_ENVIRONMENT_VARIABLES]: Record<string, string>;
22
29
  [CloudSettingsKeys.MACHINE_CLASS_PRIORITY]: LudeoCastV2MachineClass[];
23
30
  [CloudSettingsKeys.SPOT_ROLLOUT]: number;
31
+ [CloudSettingsKeys.SCALING]: CloudScalingMode;
24
32
  }
25
33
 
26
-
27
34
  export const MACHINE_CLASS_PRIORITY_DEFAULT_VALUES = [
28
35
  LudeoCastV2MachineClass.N1_STANDARD_8,
29
36
  LudeoCastV2MachineClass.G4DN_2XLARGE,
30
37
  LudeoCastV2MachineClass.N1_STANDARD_16,
31
- LudeoCastV2MachineClass.G4DN_2XLARGE,
38
+ LudeoCastV2MachineClass.G4DN_4XLARGE,
39
+ LudeoCastV2MachineClass.G5_2XLARGE,
40
+ LudeoCastV2MachineClass.G5_4XLARGE,
32
41
  LudeoCastV2MachineClass.G2_STANDARD_16,
33
42
  LudeoCastV2MachineClass.G6_2XLARGE,
34
43
  LudeoCastV2MachineClass.G6_4XLARGE,
44
+ LudeoCastV2MachineClass.G6E_2XLARGE,
45
+ LudeoCastV2MachineClass.G6E_4XLARGE,
35
46
  LudeoCastV2MachineClass.G4_STANDARD_48,
47
+ LudeoCastV2MachineClass.G7E_2XLARGE,
48
+ LudeoCastV2MachineClass.G7E_4XLARGE,
49
+
36
50
  ];
37
51
 
38
52
  // Create a type-safe CloudSettings type
@@ -41,14 +55,13 @@ export type CloudSettings = {
41
55
  };
42
56
 
43
57
  // Type-safe getter function that returns the specific value type for each key
58
+ /** Uses nullish coalescing so numeric 0 (e.g. SPOT_ROLLOUT) is not replaced by defaults. */
44
59
  export const getCloudSettingsByKey = <K extends CloudSettingsKeys>(
45
60
  key: K,
46
- cloudSettings: CloudSettings
61
+ cloudSettings: CloudSettings,
47
62
  ): CloudSettingsTypeMap[K] => {
48
- return (
49
- cloudSettings[key] ||
50
- (CLOUD_SETTINGS_DEFAULT_VALUES[key].defaultValue as CloudSettingsTypeMap[K])
51
- );
63
+ const raw = cloudSettings[key];
64
+ return (raw ?? CLOUD_SETTINGS_DEFAULT_VALUES[key].defaultValue) as CloudSettingsTypeMap[K];
52
65
  };
53
66
 
54
67
  // Discriminated union for type-safe configuration
@@ -82,6 +95,12 @@ export type CloudSettingConfig =
82
95
  key: CloudSettingsKeys;
83
96
  displayKey: string;
84
97
  defaultValue: LudeoCastV2MachineClass[];
98
+ }
99
+ | {
100
+ type: "enum";
101
+ key: CloudSettingsKeys;
102
+ displayKey: string;
103
+ defaultValue: CloudScalingMode;
85
104
  };
86
105
 
87
106
  export const CLOUD_SETTINGS_DEFAULT_VALUES: Record<
@@ -128,12 +147,18 @@ export const CLOUD_SETTINGS_DEFAULT_VALUES: Record<
128
147
  type: "array",
129
148
  key: CloudSettingsKeys.MACHINE_CLASS_PRIORITY,
130
149
  displayKey: "Machine Class Priority",
131
- defaultValue: MACHINE_CLASS_PRIORITY_DEFAULT_VALUES
150
+ defaultValue: MACHINE_CLASS_PRIORITY_DEFAULT_VALUES,
132
151
  },
133
152
  [CloudSettingsKeys.SPOT_ROLLOUT]: {
134
153
  type: "number",
135
154
  key: CloudSettingsKeys.SPOT_ROLLOUT,
136
155
  displayKey: "Spot Rollout (%)",
137
- defaultValue: 0,
156
+ defaultValue: 100,
138
157
  },
139
- };
158
+ [CloudSettingsKeys.SCALING]: {
159
+ type: "enum",
160
+ key: CloudSettingsKeys.SCALING,
161
+ displayKey: "Scaling",
162
+ defaultValue: CloudScalingMode.AUTO_SCALING,
163
+ },
164
+ };
@@ -0,0 +1,57 @@
1
+ import { LudeoCastV2MachineClass } from "./machine-class";
2
+
3
+ export enum LudeocastGpuType {
4
+ AMPERE = "ampere",
5
+ BOHR = "bohr",
6
+ T4 = "T4",
7
+ L4 = "L4",
8
+ A10G = "A10G",
9
+ L40S = "L40S",
10
+ RTXPRO6000 = "RTXPRO6000",
11
+ }
12
+
13
+ export const SPOT_SUFFIX = "-spot";
14
+
15
+ export const isSpotMachineClass = (machineClass: string): boolean => machineClass.endsWith(SPOT_SUFFIX);
16
+
17
+ export const stripSpotSuffix = (value: string): string => (isSpotMachineClass(value) ? value.slice(0, -SPOT_SUFFIX.length) : value);
18
+
19
+ /** Canonical machine-class → gpu-type map (ludeocast pool agent / site-controller Redis & S3). */
20
+ export const MACHINE_CLASS_TO_GPU_TYPE: Record<LudeoCastV2MachineClass, LudeocastGpuType> = {
21
+ // NVIDIA T4 (Turing)
22
+ [LudeoCastV2MachineClass.N1_STANDARD_8]: LudeocastGpuType.T4,
23
+ [LudeoCastV2MachineClass.N1_STANDARD_16]: LudeocastGpuType.T4,
24
+ [LudeoCastV2MachineClass.G4DN_2XLARGE]: LudeocastGpuType.T4,
25
+ [LudeoCastV2MachineClass.G4DN_4XLARGE]: LudeocastGpuType.T4,
26
+ // NVIDIA A10G (Ampere)
27
+ [LudeoCastV2MachineClass.G5_2XLARGE]: LudeocastGpuType.A10G,
28
+ [LudeoCastV2MachineClass.G5_4XLARGE]: LudeocastGpuType.A10G,
29
+ // NVIDIA L4 (Ada Lovelace)
30
+ [LudeoCastV2MachineClass.G2_STANDARD_16]: LudeocastGpuType.L4,
31
+ [LudeoCastV2MachineClass.G6_2XLARGE]: LudeocastGpuType.L4,
32
+ [LudeoCastV2MachineClass.G6_4XLARGE]: LudeocastGpuType.L4,
33
+ // NVIDIA L40S (Ada Lovelace)
34
+ [LudeoCastV2MachineClass.G6E_2XLARGE]: LudeocastGpuType.L40S,
35
+ [LudeoCastV2MachineClass.G6E_4XLARGE]: LudeocastGpuType.L40S,
36
+ // NVIDIA RTX PRO 6000 Blackwell Server Edition
37
+ [LudeoCastV2MachineClass.G7E_2XLARGE]: LudeocastGpuType.RTXPRO6000,
38
+ [LudeoCastV2MachineClass.G7E_4XLARGE]: LudeocastGpuType.RTXPRO6000,
39
+ [LudeoCastV2MachineClass.G4_STANDARD_48]: LudeocastGpuType.RTXPRO6000,
40
+ [LudeoCastV2MachineClass.G4_STANDARD_24]: LudeocastGpuType.RTXPRO6000,
41
+ [LudeoCastV2MachineClass.G4_STANDARD_12]: LudeocastGpuType.RTXPRO6000,
42
+ [LudeoCastV2MachineClass.G4_STANDARD_6]: LudeocastGpuType.RTXPRO6000,
43
+ };
44
+
45
+ export function getGpuTypeByMachineClass(machineClass: string | LudeoCastV2MachineClass): LudeocastGpuType {
46
+ const baseMachineClass = stripSpotSuffix(machineClass as string) as LudeoCastV2MachineClass;
47
+ const gpuType = MACHINE_CLASS_TO_GPU_TYPE[baseMachineClass];
48
+ if (!gpuType) throw new Error(`No GPU type mapping for machine class: ${machineClass}`);
49
+ return gpuType;
50
+ }
51
+
52
+ /** For callers using raw pool `machineClass` strings (e.g. site-controller Redis / S3 path segments). */
53
+ export function tryResolveGpuTypeByMachineClass(machineClass: string | undefined): LudeocastGpuType | undefined {
54
+ if (!machineClass?.trim()) return undefined;
55
+ const base = stripSpotSuffix(machineClass.trim()) as LudeoCastV2MachineClass;
56
+ return MACHINE_CLASS_TO_GPU_TYPE[base];
57
+ }
@@ -1,3 +1,4 @@
1
+ export * from "./machine-resource-meta";
1
2
  export * from "./resource-provider-settings";
2
3
  export * from "./provider-settings";
3
4
  export * from "./request-data";
@@ -5,3 +6,4 @@ export * from "./game-creation-response";
5
6
  export * from "./allocation-data";
6
7
  export * from "./machine-provider-settings";
7
8
  export * from "./machine-class";
9
+ export * from "./gpu-type";
@@ -10,6 +10,12 @@ export enum LudeoCastV2MachineClass {
10
10
  // AWS
11
11
  G4DN_2XLARGE = "g4dn.2xlarge",
12
12
  G4DN_4XLARGE = "g4dn.4xlarge",
13
+ G5_2XLARGE = "g5.2xlarge",
14
+ G5_4XLARGE = "g5.4xlarge",
13
15
  G6_2XLARGE = "g6.2xlarge",
14
16
  G6_4XLARGE = "g6.4xlarge",
17
+ G6E_2XLARGE = "g6e.2xlarge",
18
+ G6E_4XLARGE = "g6e.4xlarge",
19
+ G7E_2XLARGE = "g7e.2xlarge",
20
+ G7E_4XLARGE = "g7e.4xlarge",
15
21
  }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Machine facts reported by the ludeocast agent on specific lifecycle milestones (not provisioning /
3
+ * pool `LudeoCastV2ProviderSettings`). Site-controller persists this shape under the machine resource
4
+ * field `meta`, merged shallowly when handling the matching MQTT `resource-update`.
5
+ *
6
+ * @example AgentReadyForCommands — include `nvidiaDriverVersion` from `nvidia-smi` in payload `meta`.
7
+ */
8
+ export interface MachineResourceMeta {
9
+ nvidiaDriverVersion?: string;
10
+ }
@@ -1,7 +1,8 @@
1
- import { IsString, IsOptional, IsObject, IsArray } from "class-validator";
1
+ import { IsString, IsOptional, IsObject, IsArray, IsUUID } from "class-validator";
2
2
  import { LudeocastV2Distributions } from "../build";
3
3
  import { MachineResourceSettings } from "../pools";
4
4
  import { LudeoCastV2MachineResourceProviderSettings } from "../cloud";
5
+ import { ValidateNestedType } from "../../../decorators";
5
6
 
6
7
  export enum MachineMode {
7
8
  PROTON = "proton",
@@ -9,6 +10,17 @@ export enum MachineMode {
9
10
  PROTON_V2 = "proton-v2",
10
11
  }
11
12
 
13
+ /** Shader / runtime artifact bundle (site-controller may fill when ENABLE_RUNTIME_ARTIFACTS is true). */
14
+ export class RuntimeArtifactsPayload {
15
+ @IsString()
16
+ latestVersion: string;
17
+
18
+ /** Presigned GET URLs for artifact objects under this version; agent consumes them in order when non-empty. */
19
+ @IsArray()
20
+ @IsString({ each: true })
21
+ downloadUrls: string[];
22
+ }
23
+
12
24
  export class ProtonGameCreationPayload {
13
25
  @IsString()
14
26
  exeRelativePath: string;
@@ -21,8 +33,16 @@ export class ProtonGameCreationPayload {
21
33
  @IsArray()
22
34
  additionalLaunchArgs?: string[];
23
35
 
24
- @IsString()
36
+ @IsUUID()
25
37
  buildId: string;
38
+
39
+ @IsOptional()
40
+ @IsString()
41
+ gameVersionId?: string;
42
+
43
+ @IsOptional()
44
+ @ValidateNestedType(() => RuntimeArtifactsPayload)
45
+ runtimeArtifacts?: RuntimeArtifactsPayload;
26
46
  }
27
47
 
28
48
  export class AndroidGameCreationPayload {