@aws/ml-container-creator 0.2.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.
Files changed (143) hide show
  1. package/LICENSE +202 -0
  2. package/LICENSE-THIRD-PARTY +68620 -0
  3. package/NOTICE +2 -0
  4. package/README.md +106 -0
  5. package/bin/cli.js +365 -0
  6. package/config/defaults.json +32 -0
  7. package/config/presets/transformers-djl.json +26 -0
  8. package/config/presets/transformers-gpu.json +24 -0
  9. package/config/presets/transformers-lmi.json +27 -0
  10. package/package.json +129 -0
  11. package/servers/README.md +419 -0
  12. package/servers/base-image-picker/catalogs/model-servers.json +1191 -0
  13. package/servers/base-image-picker/catalogs/python-slim.json +38 -0
  14. package/servers/base-image-picker/catalogs/triton-backends.json +51 -0
  15. package/servers/base-image-picker/catalogs/triton.json +38 -0
  16. package/servers/base-image-picker/index.js +495 -0
  17. package/servers/base-image-picker/manifest.json +17 -0
  18. package/servers/base-image-picker/package.json +15 -0
  19. package/servers/hyperpod-cluster-picker/LICENSE +202 -0
  20. package/servers/hyperpod-cluster-picker/index.js +424 -0
  21. package/servers/hyperpod-cluster-picker/manifest.json +14 -0
  22. package/servers/hyperpod-cluster-picker/package.json +17 -0
  23. package/servers/instance-recommender/LICENSE +202 -0
  24. package/servers/instance-recommender/catalogs/instances.json +852 -0
  25. package/servers/instance-recommender/index.js +284 -0
  26. package/servers/instance-recommender/manifest.json +16 -0
  27. package/servers/instance-recommender/package.json +15 -0
  28. package/servers/lib/LICENSE +202 -0
  29. package/servers/lib/bedrock-client.js +160 -0
  30. package/servers/lib/custom-validators.js +46 -0
  31. package/servers/lib/dynamic-resolver.js +36 -0
  32. package/servers/lib/package.json +11 -0
  33. package/servers/lib/schemas/image-catalog.schema.json +185 -0
  34. package/servers/lib/schemas/instances.schema.json +124 -0
  35. package/servers/lib/schemas/manifest.schema.json +64 -0
  36. package/servers/lib/schemas/model-catalog.schema.json +91 -0
  37. package/servers/lib/schemas/regions.schema.json +26 -0
  38. package/servers/lib/schemas/triton-backends.schema.json +51 -0
  39. package/servers/model-picker/catalogs/jumpstart-public.json +66 -0
  40. package/servers/model-picker/catalogs/popular-diffusors.json +88 -0
  41. package/servers/model-picker/catalogs/popular-transformers.json +226 -0
  42. package/servers/model-picker/index.js +1693 -0
  43. package/servers/model-picker/manifest.json +18 -0
  44. package/servers/model-picker/package.json +20 -0
  45. package/servers/region-picker/LICENSE +202 -0
  46. package/servers/region-picker/catalogs/regions.json +263 -0
  47. package/servers/region-picker/index.js +230 -0
  48. package/servers/region-picker/manifest.json +16 -0
  49. package/servers/region-picker/package.json +15 -0
  50. package/src/app.js +1007 -0
  51. package/src/copy-tpl.js +77 -0
  52. package/src/lib/accelerator-validator.js +39 -0
  53. package/src/lib/asset-manager.js +385 -0
  54. package/src/lib/aws-profile-parser.js +181 -0
  55. package/src/lib/bootstrap-command-handler.js +1647 -0
  56. package/src/lib/bootstrap-config.js +238 -0
  57. package/src/lib/ci-register-helpers.js +124 -0
  58. package/src/lib/ci-report-helpers.js +158 -0
  59. package/src/lib/ci-stage-helpers.js +268 -0
  60. package/src/lib/cli-handler.js +529 -0
  61. package/src/lib/comment-generator.js +544 -0
  62. package/src/lib/community-reports-validator.js +91 -0
  63. package/src/lib/config-manager.js +2106 -0
  64. package/src/lib/configuration-exporter.js +204 -0
  65. package/src/lib/configuration-manager.js +695 -0
  66. package/src/lib/configuration-matcher.js +221 -0
  67. package/src/lib/cpu-validator.js +36 -0
  68. package/src/lib/cuda-validator.js +57 -0
  69. package/src/lib/deployment-config-resolver.js +103 -0
  70. package/src/lib/deployment-entry-schema.js +125 -0
  71. package/src/lib/deployment-registry.js +598 -0
  72. package/src/lib/docker-introspection-validator.js +51 -0
  73. package/src/lib/engine-prefix-resolver.js +60 -0
  74. package/src/lib/huggingface-client.js +172 -0
  75. package/src/lib/key-value-parser.js +37 -0
  76. package/src/lib/known-flags-validator.js +200 -0
  77. package/src/lib/manifest-cli.js +280 -0
  78. package/src/lib/mcp-client.js +303 -0
  79. package/src/lib/mcp-command-handler.js +532 -0
  80. package/src/lib/neuron-validator.js +80 -0
  81. package/src/lib/parameter-schema-validator.js +284 -0
  82. package/src/lib/prompt-runner.js +1349 -0
  83. package/src/lib/prompts.js +1138 -0
  84. package/src/lib/registry-command-handler.js +519 -0
  85. package/src/lib/registry-loader.js +198 -0
  86. package/src/lib/rocm-validator.js +80 -0
  87. package/src/lib/schema-validator.js +157 -0
  88. package/src/lib/sensitive-redactor.js +59 -0
  89. package/src/lib/template-engine.js +156 -0
  90. package/src/lib/template-manager.js +341 -0
  91. package/src/lib/validation-engine.js +314 -0
  92. package/src/prompt-adapter.js +63 -0
  93. package/templates/Dockerfile +300 -0
  94. package/templates/IAM_PERMISSIONS.md +84 -0
  95. package/templates/MIGRATION.md +488 -0
  96. package/templates/PROJECT_README.md +439 -0
  97. package/templates/TEMPLATE_SYSTEM.md +243 -0
  98. package/templates/buildspec.yml +64 -0
  99. package/templates/code/chat_template.jinja +1 -0
  100. package/templates/code/flask/gunicorn_config.py +35 -0
  101. package/templates/code/flask/wsgi.py +10 -0
  102. package/templates/code/model_handler.py +387 -0
  103. package/templates/code/serve +300 -0
  104. package/templates/code/serve.py +175 -0
  105. package/templates/code/serving.properties +105 -0
  106. package/templates/code/start_server.py +39 -0
  107. package/templates/code/start_server.sh +39 -0
  108. package/templates/diffusors/Dockerfile +72 -0
  109. package/templates/diffusors/patch_image_api.py +35 -0
  110. package/templates/diffusors/serve +115 -0
  111. package/templates/diffusors/start_server.sh +114 -0
  112. package/templates/do/.gitkeep +1 -0
  113. package/templates/do/README.md +541 -0
  114. package/templates/do/build +83 -0
  115. package/templates/do/ci +681 -0
  116. package/templates/do/clean +811 -0
  117. package/templates/do/config +260 -0
  118. package/templates/do/deploy +1560 -0
  119. package/templates/do/export +306 -0
  120. package/templates/do/logs +319 -0
  121. package/templates/do/manifest +12 -0
  122. package/templates/do/push +119 -0
  123. package/templates/do/register +580 -0
  124. package/templates/do/run +113 -0
  125. package/templates/do/submit +417 -0
  126. package/templates/do/test +1147 -0
  127. package/templates/hyperpod/configmap.yaml +24 -0
  128. package/templates/hyperpod/deployment.yaml +71 -0
  129. package/templates/hyperpod/pvc.yaml +42 -0
  130. package/templates/hyperpod/service.yaml +17 -0
  131. package/templates/nginx-diffusors.conf +74 -0
  132. package/templates/nginx-predictors.conf +47 -0
  133. package/templates/nginx-tensorrt.conf +74 -0
  134. package/templates/requirements.txt +61 -0
  135. package/templates/sample_model/test_inference.py +123 -0
  136. package/templates/sample_model/train_abalone.py +252 -0
  137. package/templates/test/test_endpoint.sh +79 -0
  138. package/templates/test/test_local_image.sh +80 -0
  139. package/templates/test/test_model_handler.py +180 -0
  140. package/templates/triton/Dockerfile +128 -0
  141. package/templates/triton/config.pbtxt +163 -0
  142. package/templates/triton/model.py +130 -0
  143. package/templates/triton/requirements.txt +11 -0
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Configuration Matcher
3
+ *
4
+ * Finds best matching configurations for user selections.
5
+ * Supports exact matching, fuzzy version matching, and pattern matching.
6
+ */
7
+
8
+ class ConfigurationMatcher {
9
+ constructor(frameworkRegistry = {}, modelRegistry = {}) {
10
+ this.frameworkRegistry = frameworkRegistry;
11
+ this.modelRegistry = modelRegistry;
12
+ }
13
+
14
+ /**
15
+ * Match framework configuration
16
+ * Tries exact match first, then finds closest compatible version
17
+ * @param {string} framework - Framework name
18
+ * @param {string} version - Framework version
19
+ * @returns {Object|null} Framework configuration or null if not found
20
+ */
21
+ matchFramework(framework, version) {
22
+ if (!Object.hasOwn(this.frameworkRegistry, framework)) {
23
+ return null;
24
+ }
25
+ const frameworkVersions = this.frameworkRegistry[framework];
26
+
27
+ // Exact match first
28
+ if (Object.hasOwn(frameworkVersions, version)) {
29
+ return {
30
+ ...frameworkVersions[version],
31
+ matchType: 'exact',
32
+ matchedVersion: version
33
+ };
34
+ }
35
+
36
+ // Find closest compatible version
37
+ const closestMatch = this.findClosestVersion(frameworkVersions, version);
38
+ if (closestMatch) {
39
+ return {
40
+ ...closestMatch.config,
41
+ matchType: 'fuzzy',
42
+ matchedVersion: closestMatch.version,
43
+ requestedVersion: version
44
+ };
45
+ }
46
+
47
+ return null;
48
+ }
49
+
50
+ /**
51
+ * Find closest compatible version using semantic versioning
52
+ * @param {Object} versions - Available versions object
53
+ * @param {string} targetVersion - Target version to match
54
+ * @returns {Object|null} Object with {version, config} or null
55
+ */
56
+ findClosestVersion(versions, targetVersion) {
57
+ const availableVersions = Object.keys(versions);
58
+ if (availableVersions.length === 0) {
59
+ return null;
60
+ }
61
+
62
+ const target = this.parseVersion(targetVersion);
63
+ if (!target) {
64
+ return null;
65
+ }
66
+
67
+ let bestMatch = null;
68
+ let smallestDiff = Infinity;
69
+
70
+ for (const version of availableVersions) {
71
+ const current = this.parseVersion(version);
72
+ if (!current) continue;
73
+
74
+ // Calculate version distance
75
+ const diff = this.calculateVersionDistance(target, current);
76
+
77
+ // Prefer versions that are >= target (forward compatible)
78
+ // But also consider older versions if no newer ones exist
79
+ if (diff < smallestDiff) {
80
+ smallestDiff = diff;
81
+ bestMatch = { version, config: versions[version] };
82
+ }
83
+ }
84
+
85
+ return bestMatch;
86
+ }
87
+
88
+ /**
89
+ * Parse semantic version string into components
90
+ * @param {string} versionString - Version string (e.g., "1.2.3")
91
+ * @returns {Object|null} Object with {major, minor, patch} or null
92
+ */
93
+ parseVersion(versionString) {
94
+ if (!versionString || typeof versionString !== 'string') {
95
+ return null;
96
+ }
97
+
98
+ // Remove 'v' prefix if present
99
+ const cleaned = versionString.replace(/^v/, '');
100
+
101
+ // Match semantic version pattern
102
+ const match = cleaned.match(/^(\d+)(?:\.(\d+))?(?:\.(\d+))?/);
103
+ if (!match) {
104
+ return null;
105
+ }
106
+
107
+ return {
108
+ major: parseInt(match[1], 10),
109
+ minor: parseInt(match[2] || '0', 10),
110
+ patch: parseInt(match[3] || '0', 10)
111
+ };
112
+ }
113
+
114
+ /**
115
+ * Calculate distance between two versions
116
+ * Lower distance means closer match
117
+ * @param {Object} target - Target version {major, minor, patch}
118
+ * @param {Object} current - Current version {major, minor, patch}
119
+ * @returns {number} Distance value
120
+ */
121
+ calculateVersionDistance(target, current) {
122
+ // Major version difference is most significant
123
+ const majorDiff = Math.abs(current.major - target.major) * 10000;
124
+
125
+ // Minor version difference
126
+ const minorDiff = Math.abs(current.minor - target.minor) * 100;
127
+
128
+ // Patch version difference
129
+ const patchDiff = Math.abs(current.patch - target.patch);
130
+
131
+ // Prefer newer versions slightly (small penalty for older versions)
132
+ const directionPenalty = current.major < target.major ? 1 :
133
+ current.major === target.major && current.minor < target.minor ? 0.5 :
134
+ current.major === target.major && current.minor === target.minor && current.patch < target.patch ? 0.1 :
135
+ 0;
136
+
137
+ return majorDiff + minorDiff + patchDiff + directionPenalty;
138
+ }
139
+
140
+ /**
141
+ * Match model configuration
142
+ * Checks exact match first, then pattern matching
143
+ * @param {string} modelId - Model ID (e.g., "meta-llama/Llama-2-7b-chat-hf")
144
+ * @returns {Object|null} Model configuration or null if not found
145
+ */
146
+ matchModel(modelId) {
147
+ if (!modelId) {
148
+ return null;
149
+ }
150
+
151
+ // Check exact match first
152
+ if (Object.hasOwn(this.modelRegistry, modelId)) {
153
+ return {
154
+ ...this.modelRegistry[modelId],
155
+ matchType: 'exact',
156
+ matchedPattern: modelId
157
+ };
158
+ }
159
+
160
+ // Try pattern matching
161
+ const patternMatch = this.matchModelPattern(modelId);
162
+ if (patternMatch) {
163
+ return {
164
+ ...patternMatch.config,
165
+ matchType: 'pattern',
166
+ matchedPattern: patternMatch.pattern,
167
+ modelId
168
+ };
169
+ }
170
+
171
+ return null;
172
+ }
173
+
174
+ /**
175
+ * Match model by pattern (e.g., "mistral*" matches "mistralai/Mistral-7B-v0.1")
176
+ * @param {string} modelId - Model ID to match
177
+ * @returns {Object|null} Object with {pattern, config} or null
178
+ */
179
+ matchModelPattern(modelId) {
180
+ if (!modelId) {
181
+ return null;
182
+ }
183
+
184
+ for (const [pattern, config] of Object.entries(this.modelRegistry)) {
185
+ if (this.matchesPattern(modelId, pattern)) {
186
+ return { pattern, config };
187
+ }
188
+ }
189
+
190
+ return null;
191
+ }
192
+
193
+ /**
194
+ * Check if a model ID matches a pattern
195
+ * Supports wildcards (*) and case-insensitive matching
196
+ * @param {string} modelId - Model ID to test
197
+ * @param {string} pattern - Pattern to match against
198
+ * @returns {boolean} True if matches
199
+ */
200
+ matchesPattern(modelId, pattern) {
201
+ if (!modelId || !pattern) {
202
+ return false;
203
+ }
204
+
205
+ // Exact match (no wildcards)
206
+ if (!pattern.includes('*')) {
207
+ return modelId.toLowerCase() === pattern.toLowerCase();
208
+ }
209
+
210
+ // Convert pattern to regex
211
+ // Escape special regex characters except *
212
+ const regexPattern = pattern
213
+ .replace(/[.+?^${}()|[\]\\]/g, '\\$&') // Escape special chars
214
+ .replace(/\*/g, '.*'); // Convert * to .*
215
+
216
+ const regex = new RegExp(`^${regexPattern}$`, 'i'); // Case-insensitive
217
+ return regex.test(modelId);
218
+ }
219
+ }
220
+
221
+ export default ConfigurationMatcher;
@@ -0,0 +1,36 @@
1
+ import AcceleratorValidator from './accelerator-validator.js';
2
+
3
+ /**
4
+ * CPU accelerator validator.
5
+ * CPU-based inference is always compatible (no version requirements).
6
+ *
7
+ * Requirements: 4.9
8
+ */
9
+ export default class CpuValidator extends AcceleratorValidator {
10
+ /**
11
+ * Validate CPU compatibility.
12
+ * CPU is always compatible - no version checking needed.
13
+ *
14
+ * @param {Object} frameworkConfig - Framework accelerator requirements
15
+ * @param {Object} instanceConfig - Instance accelerator capabilities
16
+ * @returns {Object} ValidationResult
17
+ */
18
+ validate(_frameworkConfig, _instanceConfig) {
19
+ return {
20
+ compatible: true,
21
+ info: 'CPU-based inference (no accelerator version requirements)'
22
+ };
23
+ }
24
+
25
+ /**
26
+ * Get version mismatch message.
27
+ * Not used for CPU since it's always compatible.
28
+ *
29
+ * @param {string} required - Required version
30
+ * @param {Array<string>|string} provided - Provided version(s)
31
+ * @returns {string} Empty string (not used for CPU)
32
+ */
33
+ getVersionMismatchMessage(_required, _provided) {
34
+ return ''; // Not used for CPU
35
+ }
36
+ }
@@ -0,0 +1,57 @@
1
+ import AcceleratorValidator from './accelerator-validator.js';
2
+
3
+ /**
4
+ * CUDA-specific accelerator validator.
5
+ * Implements CUDA major.minor version comparison.
6
+ *
7
+ * Requirements: 4.11, 4.12, 4.13, 4.14, 4.22
8
+ */
9
+ export default class CudaValidator extends AcceleratorValidator {
10
+ /**
11
+ * Validate CUDA version compatibility.
12
+ * CUDA uses major.minor versioning (e.g., 12.1, 11.8).
13
+ *
14
+ * @param {Object} frameworkConfig - Framework accelerator requirements
15
+ * @param {Object} instanceConfig - Instance accelerator capabilities
16
+ * @returns {Object} ValidationResult
17
+ */
18
+ validate(frameworkConfig, instanceConfig) {
19
+ const required = frameworkConfig.accelerator;
20
+ const provided = instanceConfig.accelerator;
21
+
22
+ // Parse required CUDA version (major.minor)
23
+ const requiredMajor = parseInt(required.version.split('.')[0]);
24
+ const requiredMinor = parseInt(required.version.split('.')[1]);
25
+
26
+ // Check if instance supports required CUDA version
27
+ // Instance must have same major version and >= minor version
28
+ const compatibleVersions = provided.versions.filter(v => {
29
+ const [major, minor] = v.split('.').map(Number);
30
+ return major === requiredMajor && minor >= requiredMinor;
31
+ });
32
+
33
+ if (compatibleVersions.length === 0) {
34
+ return {
35
+ compatible: false,
36
+ error: this.getVersionMismatchMessage(required.version, provided.versions)
37
+ };
38
+ }
39
+
40
+ return {
41
+ compatible: true,
42
+ info: `Using CUDA ${compatibleVersions[0]} (compatible with required ${required.version})`
43
+ };
44
+ }
45
+
46
+ /**
47
+ * Get user-friendly error message for CUDA version mismatch.
48
+ *
49
+ * @param {string} required - Required CUDA version
50
+ * @param {Array<string>} provided - Provided CUDA versions
51
+ * @returns {string} User-friendly error message
52
+ */
53
+ getVersionMismatchMessage(required, provided) {
54
+ return `Framework requires CUDA ${required}, but instance only supports ${provided.join(', ')}. ` +
55
+ 'Consider using ml.g5 or ml.g6 instances for CUDA 12.x support.';
56
+ }
57
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * DeploymentConfigResolver
3
+ *
4
+ * Decomposes a flat deployment-config string into a structured
5
+ * { architecture, backend, engine } triple. This is the single source
6
+ * of truth for all valid deployment-config values, replacing the
7
+ * scattered split('-') logic that was previously in ConfigManager,
8
+ * PromptRunner, and index.js.
9
+ *
10
+ * Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7
11
+ */
12
+
13
+ /**
14
+ * Canonical mapping from deployment-config strings to structured parts.
15
+ * 2 http + 5 transformers + 7 triton + 1 diffusors = 15 total configs.
16
+ */
17
+ const CANONICAL_CONFIGS = new Map([
18
+ // HTTP architecture (2)
19
+ ['http-flask', { architecture: 'http', backend: 'flask', engine: null }],
20
+ ['http-fastapi', { architecture: 'http', backend: 'fastapi', engine: null }],
21
+
22
+ // Transformers architecture (5)
23
+ ['transformers-vllm', { architecture: 'transformers', backend: 'vllm', engine: null }],
24
+ ['transformers-sglang', { architecture: 'transformers', backend: 'sglang', engine: null }],
25
+ ['transformers-tensorrt-llm', { architecture: 'transformers', backend: 'tensorrt-llm', engine: null }],
26
+ ['transformers-lmi', { architecture: 'transformers', backend: 'lmi', engine: null }],
27
+ ['transformers-djl', { architecture: 'transformers', backend: 'djl', engine: null }],
28
+
29
+ // Triton architecture (7)
30
+ ['triton-fil', { architecture: 'triton', backend: 'fil', engine: null }],
31
+ ['triton-onnxruntime', { architecture: 'triton', backend: 'onnxruntime', engine: null }],
32
+ ['triton-tensorflow', { architecture: 'triton', backend: 'tensorflow', engine: null }],
33
+ ['triton-pytorch', { architecture: 'triton', backend: 'pytorch', engine: null }],
34
+ ['triton-vllm', { architecture: 'triton', backend: 'vllm', engine: null }],
35
+ ['triton-tensorrtllm', { architecture: 'triton', backend: 'tensorrtllm', engine: null }],
36
+ ['triton-python', { architecture: 'triton', backend: 'python', engine: null }],
37
+
38
+ // Diffusors architecture (1)
39
+ ['diffusors-vllm-omni', { architecture: 'diffusors', backend: 'vllm-omni', engine: null }],
40
+ ])
41
+
42
+ export default class DeploymentConfigResolver {
43
+ /**
44
+ * Decompose a deployment-config string into its constituent parts.
45
+ *
46
+ * @param {string} deploymentConfig - e.g. 'http-flask', 'transformers-vllm', 'triton-fil'
47
+ * @returns {{ architecture: string, backend: string, engine: string|null }}
48
+ * @throws {Error} if the deployment-config is not one of the 15 canonical values
49
+ */
50
+ decompose(deploymentConfig) {
51
+ const parts = CANONICAL_CONFIGS.get(deploymentConfig)
52
+ if (!parts) {
53
+ const valid = this.getAllConfigs().join(', ')
54
+ throw new Error(
55
+ `Unsupported deployment-config: ${deploymentConfig}. Valid configs: ${valid}`
56
+ )
57
+ }
58
+ return { ...parts }
59
+ }
60
+
61
+ /**
62
+ * Compose a deployment-config string from structured parts.
63
+ * Inverse of decompose().
64
+ *
65
+ * @param {{ architecture: string, backend: string, engine?: string }} parts
66
+ * @returns {string}
67
+ */
68
+ compose(parts) {
69
+ return `${parts.architecture}-${parts.backend}`
70
+ }
71
+
72
+ /**
73
+ * Get all 15 valid deployment-config strings.
74
+ *
75
+ * @returns {string[]}
76
+ */
77
+ getAllConfigs() {
78
+ return [...CANONICAL_CONFIGS.keys()]
79
+ }
80
+
81
+ /**
82
+ * Get valid deployment-config strings for a given architecture.
83
+ *
84
+ * @param {string} architecture - 'http' | 'transformers' | 'triton' | 'diffusors'
85
+ * @returns {string[]}
86
+ */
87
+ getConfigsForArchitecture(architecture) {
88
+ return this.getAllConfigs().filter(
89
+ (dc) => CANONICAL_CONFIGS.get(dc).architecture === architecture
90
+ )
91
+ }
92
+
93
+ /**
94
+ * Check if a deployment-config string is valid.
95
+ * Old-format strings (e.g. 'sklearn-flask') return false.
96
+ *
97
+ * @param {string} deploymentConfig
98
+ * @returns {boolean}
99
+ */
100
+ isValid(deploymentConfig) {
101
+ return CANONICAL_CONFIGS.has(deploymentConfig)
102
+ }
103
+ }
@@ -0,0 +1,125 @@
1
+ /**
2
+ * JSON Schema for Deployment Entry
3
+ *
4
+ * Defines the structure and validation rules for deployment registry entries.
5
+ * Each entry captures the full configuration state and outcome of a single
6
+ * ML model deployment.
7
+ */
8
+
9
+ export default {
10
+ $schema: 'http://json-schema.org/draft-07/schema#',
11
+ type: 'object',
12
+ required: [
13
+ 'id',
14
+ 'timestamp',
15
+ 'status',
16
+ 'deployment',
17
+ 'model',
18
+ 'infrastructure',
19
+ 'configuration',
20
+ 'outcome',
21
+ 'metadata'
22
+ ],
23
+ properties: {
24
+ id: {
25
+ type: 'string',
26
+ pattern: '^[0-9a-f]{8}$'
27
+ },
28
+ timestamp: {
29
+ type: 'string',
30
+ pattern: '^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$'
31
+ },
32
+ status: {
33
+ type: 'string',
34
+ enum: ['success', 'partial', 'failed']
35
+ },
36
+ deployment: {
37
+ type: 'object',
38
+ required: ['deploymentConfig', 'architecture', 'backend'],
39
+ properties: {
40
+ deploymentConfig: {
41
+ type: 'string',
42
+ minLength: 1
43
+ },
44
+ architecture: {
45
+ type: 'string',
46
+ enum: ['http', 'transformers', 'triton', 'diffusors']
47
+ },
48
+ backend: {
49
+ type: 'string',
50
+ minLength: 1
51
+ },
52
+ baseImage: {
53
+ type: ['string', 'null']
54
+ },
55
+ deploymentTarget: {
56
+ type: ['string', 'null']
57
+ },
58
+ buildTarget: {
59
+ type: ['string', 'null']
60
+ }
61
+ }
62
+ },
63
+ model: {
64
+ type: 'object',
65
+ required: ['modelName'],
66
+ properties: {
67
+ modelName: {
68
+ type: 'string',
69
+ minLength: 1
70
+ },
71
+ modelFormat: {
72
+ type: ['string', 'null']
73
+ }
74
+ }
75
+ },
76
+ infrastructure: {
77
+ type: 'object',
78
+ properties: {
79
+ instanceType: {
80
+ type: ['string', 'null']
81
+ },
82
+ region: {
83
+ type: ['string', 'null']
84
+ },
85
+ roleArn: {
86
+ type: ['string', 'null']
87
+ }
88
+ }
89
+ },
90
+ configuration: {
91
+ type: 'object',
92
+ required: ['parameters'],
93
+ properties: {
94
+ parameters: {
95
+ type: 'object'
96
+ }
97
+ }
98
+ },
99
+ outcome: {
100
+ type: 'object',
101
+ properties: {
102
+ notes: {
103
+ type: ['string', 'null']
104
+ }
105
+ }
106
+ },
107
+ metadata: {
108
+ type: 'object',
109
+ required: ['generatorVersion', 'source'],
110
+ properties: {
111
+ generatorVersion: {
112
+ type: 'string',
113
+ minLength: 1
114
+ },
115
+ source: {
116
+ type: 'string',
117
+ enum: ['local', 'imported', 'community']
118
+ },
119
+ importedFrom: {
120
+ type: ['string', 'null']
121
+ }
122
+ }
123
+ }
124
+ }
125
+ };