@aws/ml-container-creator 0.2.4 → 0.2.6

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 (61) hide show
  1. package/README.md +62 -298
  2. package/bin/cli.js +7 -2
  3. package/package.json +7 -8
  4. package/servers/base-image-picker/index.js +3 -3
  5. package/servers/base-image-picker/manifest.json +4 -2
  6. package/servers/instance-sizer/index.js +561 -0
  7. package/servers/instance-sizer/lib/instance-ranker.js +245 -0
  8. package/servers/instance-sizer/lib/model-resolver.js +265 -0
  9. package/servers/instance-sizer/lib/vram-estimator.js +177 -0
  10. package/servers/instance-sizer/manifest.json +17 -0
  11. package/servers/instance-sizer/package.json +15 -0
  12. package/servers/{instance-recommender → lib}/catalogs/instances.json +136 -34
  13. package/servers/{base-image-picker → lib}/catalogs/model-servers.json +19 -249
  14. package/servers/lib/catalogs/model-sizes.json +131 -0
  15. package/servers/lib/catalogs/models.json +602 -0
  16. package/servers/{model-picker → lib}/catalogs/popular-diffusors.json +32 -10
  17. package/servers/{model-picker → lib}/catalogs/popular-transformers.json +59 -26
  18. package/servers/{base-image-picker → lib}/catalogs/python-slim.json +12 -12
  19. package/servers/lib/schemas/image-catalog.schema.json +0 -12
  20. package/servers/lib/schemas/instances.schema.json +29 -0
  21. package/servers/lib/schemas/model-catalog.schema.json +12 -10
  22. package/servers/lib/schemas/unified-model-catalog.schema.json +129 -0
  23. package/servers/model-picker/index.js +2 -3
  24. package/servers/model-picker/manifest.json +2 -3
  25. package/servers/region-picker/index.js +1 -1
  26. package/servers/region-picker/manifest.json +1 -1
  27. package/src/app.js +17 -0
  28. package/src/lib/bootstrap-command-handler.js +38 -0
  29. package/src/lib/cli-handler.js +3 -3
  30. package/src/lib/config-manager.js +4 -1
  31. package/src/lib/configuration-manager.js +2 -2
  32. package/src/lib/cross-cutting-checker.js +341 -0
  33. package/src/lib/dry-run-validator.js +78 -0
  34. package/src/lib/generation-validator.js +102 -0
  35. package/src/lib/mcp-validator-config.js +89 -0
  36. package/src/lib/payload-builder.js +153 -0
  37. package/src/lib/prompt-runner.js +445 -135
  38. package/src/lib/prompts.js +1 -1
  39. package/src/lib/registry-loader.js +5 -5
  40. package/src/lib/schema-sync.js +203 -0
  41. package/src/lib/schema-validation-engine.js +195 -0
  42. package/src/lib/service-model-parser.js +102 -0
  43. package/src/lib/validate-runner.js +167 -0
  44. package/src/lib/validation-report.js +133 -0
  45. package/src/lib/validators/base-validator.js +36 -0
  46. package/src/lib/validators/catalog-validator.js +177 -0
  47. package/src/lib/validators/enum-validator.js +120 -0
  48. package/src/lib/validators/required-field-validator.js +150 -0
  49. package/src/lib/validators/type-validator.js +313 -0
  50. package/templates/Dockerfile +1 -1
  51. package/templates/do/build +15 -5
  52. package/templates/do/run +5 -1
  53. package/templates/do/validate +61 -0
  54. package/servers/instance-recommender/LICENSE +0 -202
  55. package/servers/instance-recommender/index.js +0 -284
  56. package/servers/instance-recommender/manifest.json +0 -16
  57. package/servers/instance-recommender/package.json +0 -15
  58. /package/servers/{model-picker → lib}/catalogs/jumpstart-public.json +0 -0
  59. /package/servers/{region-picker → lib}/catalogs/regions.json +0 -0
  60. /package/servers/{base-image-picker → lib}/catalogs/triton-backends.json +0 -0
  61. /package/servers/{base-image-picker → lib}/catalogs/triton.json +0 -0
@@ -0,0 +1,89 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * MCP Validator Configuration Reader
6
+ *
7
+ * Reads smart-mode validator configuration from config/mcp.json.
8
+ * When a smart-mode validator is configured, it is queried only when --smart is passed.
9
+ * The actual MCP spawning is a FUTURE integration point — this module implements
10
+ * configuration reading and provides a stub for the spawning.
11
+ *
12
+ * Expected format in config/mcp.json:
13
+ * {
14
+ * "mcpServers": { ... existing servers ... },
15
+ * "smartValidators": [
16
+ * {
17
+ * "name": "bedrock-validator",
18
+ * "command": "node",
19
+ * "args": ["path/to/validator.js"],
20
+ * "timeout": 15000,
21
+ * "enabled": true
22
+ * }
23
+ * ]
24
+ * }
25
+ *
26
+ * Requirements: 15.6
27
+ */
28
+
29
+ import { existsSync, readFileSync } from 'node:fs';
30
+ import path from 'node:path';
31
+
32
+ /**
33
+ * Load smart-mode validator configuration from config/mcp.json.
34
+ *
35
+ * @param {string} [configPath] - Override path to mcp.json (defaults to config/mcp.json relative to project root)
36
+ * @returns {{ validators: Array, loaded: boolean }}
37
+ */
38
+ export function loadSmartValidatorConfig(configPath) {
39
+ const resolvedPath = configPath || path.resolve('config', 'mcp.json');
40
+
41
+ if (!existsSync(resolvedPath)) {
42
+ return { validators: [], loaded: false };
43
+ }
44
+
45
+ try {
46
+ const content = readFileSync(resolvedPath, 'utf8');
47
+ const config = JSON.parse(content);
48
+
49
+ const smartValidators = config.smartValidators || [];
50
+
51
+ // Filter to only enabled validators
52
+ const enabledValidators = smartValidators.filter(v => v.enabled !== false);
53
+
54
+ return {
55
+ validators: enabledValidators.map(v => ({
56
+ name: v.name || 'unnamed-smart-validator',
57
+ command: v.command || 'node',
58
+ args: v.args || [],
59
+ timeout: v.timeout || 15000,
60
+ enabled: true
61
+ })),
62
+ loaded: true
63
+ };
64
+ } catch {
65
+ return { validators: [], loaded: false };
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Spawn a smart-mode validator child process and pass context via stdio.
71
+ * FUTURE INTEGRATION POINT — currently returns an empty findings array.
72
+ *
73
+ * @param {Object} validatorConfig - Configuration for the validator
74
+ * @param {string} validatorConfig.name - Validator name
75
+ * @param {string} validatorConfig.command - Command to spawn
76
+ * @param {Array} validatorConfig.args - Arguments for the command
77
+ * @param {number} validatorConfig.timeout - Timeout in milliseconds
78
+ * @param {Object} context - The full ValidationContext (JSON-serializable)
79
+ * @param {Object} [options]
80
+ * @param {Array} [options.priorFindings] - Findings from static validators
81
+ * @returns {Promise<Array>} Array of findings from the MCP validator (currently empty stub)
82
+ */
83
+ export async function spawnSmartValidator(validatorConfig, context, _options = {}) {
84
+ // FUTURE: Spawn child process, pass context via stdio, collect findings
85
+ // For now, return empty findings array as a stub
86
+ return [];
87
+ }
88
+
89
+ export default { loadSmartValidatorConfig, spawnSmartValidator };
@@ -0,0 +1,153 @@
1
+ /* eslint-disable eqeqeq */
2
+ /**
3
+ * Constructs AWS API payloads from configuration values.
4
+ * Produces a JSON-serializable ValidationContext for the validation pipeline.
5
+ *
6
+ * Requirements: 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8
7
+ */
8
+ export default class PayloadBuilder {
9
+ /**
10
+ * Build all payloads for a deployment configuration.
11
+ * @param {Object} config - Configuration from do/config or generator answers
12
+ * @param {string} deploymentTarget - 'realtime-inference' | 'async-inference' | 'batch-transform'
13
+ * @returns {Object} ValidationContext (JSON-serializable)
14
+ */
15
+ build(config, deploymentTarget) {
16
+ const payloads = {};
17
+
18
+ const endpointConfig = this.buildCreateEndpointConfig(config);
19
+ if (endpointConfig && Object.keys(endpointConfig).length > 0) {
20
+ payloads['sagemaker:CreateEndpointConfig'] = endpointConfig;
21
+ }
22
+
23
+ const icPayload = this.buildCreateInferenceComponent(config);
24
+ if (icPayload && Object.keys(icPayload).length > 0) {
25
+ payloads['sagemaker:CreateInferenceComponent'] = icPayload;
26
+ }
27
+
28
+ if (deploymentTarget === 'async-inference') {
29
+ const modelPayload = this.buildCreateModel(config);
30
+ if (modelPayload && Object.keys(modelPayload).length > 0) {
31
+ payloads['sagemaker:CreateModel'] = modelPayload;
32
+ }
33
+ }
34
+
35
+ if (deploymentTarget === 'batch-transform') {
36
+ const transformPayload = this.buildCreateTransformJob(config);
37
+ if (transformPayload && Object.keys(transformPayload).length > 0) {
38
+ payloads['sagemaker:CreateTransformJob'] = transformPayload;
39
+ }
40
+ }
41
+
42
+ // Filter out undefined values from config to ensure JSON-serializability
43
+ const cleanConfig = {};
44
+ for (const [key, value] of Object.entries(config)) {
45
+ if (value !== undefined) {
46
+ cleanConfig[key] = value;
47
+ }
48
+ }
49
+
50
+ return {
51
+ payloads,
52
+ config: cleanConfig,
53
+ deploymentTarget,
54
+ metadata: {
55
+ generatedAt: new Date().toISOString(),
56
+ generatorVersion: '0.2.5',
57
+ services: [...new Set(Object.keys(payloads).map(k => k.split(':')[0]))]
58
+ }
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Build CreateEndpointConfig payload.
64
+ * @param {Object} config
65
+ * @returns {Object} AWS API payload
66
+ */
67
+ buildCreateEndpointConfig(config) {
68
+ const variant = {};
69
+
70
+ if (config.INSTANCE_TYPE != null) variant.InstanceType = config.INSTANCE_TYPE;
71
+ if (config.INFERENCE_AMI_VERSION != null) variant.InferenceAmiVersion = config.INFERENCE_AMI_VERSION;
72
+ if (config.ENDPOINT_VARIANT_NAME != null) variant.VariantName = config.ENDPOINT_VARIANT_NAME;
73
+ if (config.ENDPOINT_INITIAL_INSTANCE_COUNT != null) variant.InitialInstanceCount = config.ENDPOINT_INITIAL_INSTANCE_COUNT;
74
+ if (config.ENDPOINT_VOLUME_SIZE != null) variant.VolumeSizeInGB = config.ENDPOINT_VOLUME_SIZE;
75
+
76
+ if (Object.keys(variant).length === 0) return {};
77
+
78
+ return {
79
+ ProductionVariants: [variant]
80
+ };
81
+ }
82
+
83
+ /**
84
+ * Build CreateInferenceComponent payload.
85
+ * @param {Object} config
86
+ * @returns {Object} AWS API payload
87
+ */
88
+ buildCreateInferenceComponent(config) {
89
+ const payload = {};
90
+ const computeResources = {};
91
+
92
+ if (config.IC_CPU_COUNT != null) computeResources.NumberOfCpuCoresRequired = config.IC_CPU_COUNT;
93
+ if (config.IC_MEMORY_SIZE != null) computeResources.MinMemoryRequiredInMb = config.IC_MEMORY_SIZE;
94
+ if (config.IC_GPU_COUNT != null) computeResources.NumberOfAcceleratorDevicesRequired = config.IC_GPU_COUNT;
95
+
96
+ if (Object.keys(computeResources).length > 0) {
97
+ payload.Specification = { ComputeResourceRequirements: computeResources };
98
+ }
99
+
100
+ if (config.IC_COPY_COUNT != null) {
101
+ payload.RuntimeConfig = { CopyCount: config.IC_COPY_COUNT };
102
+ }
103
+
104
+ return payload;
105
+ }
106
+
107
+ /**
108
+ * Build CreateModel payload (async inference).
109
+ * @param {Object} config
110
+ * @returns {Object} AWS API payload
111
+ */
112
+ buildCreateModel(config) {
113
+ const payload = {};
114
+
115
+ if (config.CONTAINER_IMAGE != null) {
116
+ payload.PrimaryContainer = { Image: config.CONTAINER_IMAGE };
117
+ if (config.MODEL_DATA_URL != null) {
118
+ payload.PrimaryContainer.ModelDataUrl = config.MODEL_DATA_URL;
119
+ }
120
+ }
121
+
122
+ if (config.ROLE_ARN != null) payload.ExecutionRoleArn = config.ROLE_ARN;
123
+
124
+ return payload;
125
+ }
126
+
127
+ /**
128
+ * Build CreateTransformJob payload (batch transform).
129
+ * @param {Object} config
130
+ * @returns {Object} AWS API payload
131
+ */
132
+ buildCreateTransformJob(config) {
133
+ const payload = {};
134
+ const transformResources = {};
135
+
136
+ if (config.INSTANCE_TYPE != null) transformResources.InstanceType = config.INSTANCE_TYPE;
137
+ if (config.BATCH_INSTANCE_COUNT != null) transformResources.InstanceCount = config.BATCH_INSTANCE_COUNT;
138
+
139
+ if (Object.keys(transformResources).length > 0) {
140
+ payload.TransformResources = transformResources;
141
+ }
142
+
143
+ if (config.BATCH_SPLIT_TYPE != null) {
144
+ payload.TransformInput = { SplitType: config.BATCH_SPLIT_TYPE };
145
+ }
146
+
147
+ if (config.BATCH_STRATEGY != null) {
148
+ payload.BatchStrategy = config.BATCH_STRATEGY;
149
+ }
150
+
151
+ return payload;
152
+ }
153
+ }