feat: Add v1beta1 DGDR API with conversion framework - #6352
Conversation
Signed-off-by: Jont828 <jt572@cornell.edu>
Signed-off-by: Jont828 <jt572@cornell.edu>
…conditions, and print cols to DGDR status Signed-off-by: Jont828 <jt572@cornell.edu>
Signed-off-by: Jont828 <jt572@cornell.edu>
Move the +kubebuilder:storageversion marker from v1alpha1 to v1beta1 for all CRDs and regenerate manifests so v1beta1 is the version persisted in etcd going forward. Signed-off-by: Jont828 <jt572@cornell.edu>
Implement the controller-runtime conversion interface for 5 CRDs: DynamoCheckpoint, DynamoComponentDeployment, DynamoGraphDeployment, DynamoGraphDeploymentScalingAdapter, and DynamoModel. v1beta1 is marked as the Hub and v1alpha1 implements ConvertTo/ConvertFrom with field-by-field mapping. DGDR is excluded because the two versions have fundamentally different schemas that cannot be losslessly converted. Signed-off-by: Jont828 <jt572@cornell.edu>
Align the Go CRD types with the Python profiler's pydantic models so that JSON serialized between operator and profiler is structurally consistent: - Introduce ModelSpec (modelName + modelCache) replacing flat model string and top-level modelCache field - Introduce BackendSpec (backend + dynamoImage) replacing flat backend enum and top-level image field - Rename ModelCacheSpec.PVCPath to ModelPathInPVC (json: modelPathInPvc) - Add WorkloadSpec.Concurrency and RequestRate fields - Add SLASpec.E2ELatency field - Replace FeaturesSpec.Planner *bool with *PlannerSpec (enabled, plannerPreDeploymentSweeping, plannerArgsList) - Replace FeaturesSpec.Mocker *bool with *MockerSpec (enabled) - Add HardwareSpec with gpuSku, vramMb, totalGpus, numGpusPerNode - Add PlannerPreDeploymentSweepMode enum (none, rapid, thorough) - Remove OptimizationType "hybrid" value - Update printcolumn JSONPaths for new nesting - Update deepcopy methods for new and changed types Signed-off-by: Jonathan Zhou <hongkuanz@nvidia.com> Signed-off-by: Jont828 <jt572@cornell.edu>
Add v1alpha1 ↔ v1beta1 conversion for DynamoGraphDeploymentRequest (DGDR) and split the monolithic conversion.go into per-type files matching the existing *_types.go naming convention. Hub marker: add DynamoGraphDeploymentRequest to v1beta1/hub.go. DGDR conversion handles three categories of field mappings: - Simple renames (Model, Backend, AutoApply, UseMocker, WorkersImage) - JSON blob ↔ structured fields (SLA ttft/itl, Workload isl/osl, ModelCache) with full-blob annotation for round-trip preservation - Annotation-based storage for v1alpha1 fields with no v1beta1 equivalent (ProfilerImage, ConfigMapRef, OutputPVC, etc.) State ↔ Phase mapping accounts for v1alpha1 "Ready" mapping to either Ready or Deployed depending on Deployment.Created context. Signed-off-by: Jont828 <jt572@cornell.edu>
Signed-off-by: Hannah Zhang <hannahz@nvidia.com>
…add-conversion-from-dgdr-v1alpha1-to-dgdr-v1beta1
Signed-off-by: Hannah Zhang <hannahz@nvidia.com>
Signed-off-by: Hannah Zhang <hannahz@nvidia.com>
Signed-off-by: Hannah Zhang <hannahz@nvidia.com>
Signed-off-by: Hannah Zhang <hannahz@nvidia.com>
WalkthroughThis change introduces a new v1beta1 API version for DynamoGraphDeploymentRequest with comprehensive profiling and deployment specifications, implements bi-directional conversion between v1alpha1 and v1beta1, generates Python Pydantic models from Go types, marks v1alpha1 as deprecated, and updates documentation accordingly. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Signed-off-by: Hannah Zhang <hannahz@nvidia.com>
There was a problem hiding this comment.
Actionable comments posted: 9
🧹 Nitpick comments (8)
deploy/operator/api/scripts/generate_pydantic_from_go.py (2)
396-406: Fragile default output path — fiveparenttraversals.The default
--outputpath climbs five directory levels from the script location and targetscomponents/src/dynamo/profiler/utils/dgdr_v1beta1_types.py. This is brittle; any directory restructuring silently writes to the wrong location. Consider resolving the repo root viagit rev-parse --show-toplevelor a sentinel file (e.g.,go.mod) instead of hard-coded parent traversals.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@deploy/operator/api/scripts/generate_pydantic_from_go.py` around lines 396 - 406, The default for the --output argument in parser.add_argument inside generate_pydantic_from_go.py is brittle because it uses five successive Path.parent traversals to reach the repo path; replace this with a robust repo-root resolution strategy (e.g., call out to git rev-parse --show-toplevel or walk upward looking for a sentinel like go.mod) and build the output Path relative to that root instead of chaining parent() calls; add a helper function (e.g., resolve_repo_root or find_sentinel_root) and use it when constructing the default for the --output argument so restructuring the repo won’t change where dgdr_v1beta1_types.py is written.
54-67: Mutable class-level dict flagged by Ruff (RUF012).
TYPE_MAPis a mutable dict as a class attribute. While it's never mutated at runtime, the linter flags it. The simplest fix is to annotate it asClassVaror usetypes.MappingProxyTypefor an immutable view.Minimal fix using ClassVar annotation
+from typing import ClassVar ... class GoToPydanticConverter: """Converts Go structs to Pydantic models""" # Type mapping from Go to Python - TYPE_MAP = { + TYPE_MAP: ClassVar[dict[str, str]] = {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@deploy/operator/api/scripts/generate_pydantic_from_go.py` around lines 54 - 67, TYPE_MAP is a mutable module-level dict flagged by Ruff RUF012; either annotate it as an immutable ClassVar typing or expose it as an immutable mapping. Fix by adding a typing annotation (e.g., from typing import ClassVar, Dict, Any; declare TYPE_MAP: ClassVar[Dict[str, Any]] = {...}) or wrap the literal with types.MappingProxyType (import types and set TYPE_MAP = types.MappingProxyType({...})), and update imports accordingly so TYPE_MAP is read-only at runtime.deploy/operator/Makefile (1)
143-152:python3is now a hard dependency formake generate(and transitively forbuild,test).Since
generatedepends ongenerate-pydantic, any environment withoutpython3(andpydanticinstalled) will fail the entire build chain. Consider either:
- Making
generate-pydantica separate opt-in target not chained intogenerate, or- Adding a guard similar to
ensure-yqthat checks forpython3andpydanticavailability.Also, the test invocation (
test_pydantic_models.py) within a generation target is slightly unconventional. If the validation fails, it blocks deepcopy generation (controller-gen objecton line 145). If this is intentional (fail-fast), it's fine—just worth noting.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@deploy/operator/Makefile` around lines 143 - 152, The generate target currently depends on generate-pydantic making python3 and pydantic required for make generate; change this by removing generate-pydantic from the generate prerequisites and either (A) add a new independent opt-in target (e.g., generate-pydantic) users run manually, or (B) introduce a guard target ensure-python (similar to ensure-yq) that checks for python3 and that pydantic can be imported (e.g., using command -v python3 and python3 -c "import pydantic") and make generate-pydantic depend on ensure-python so generation only fails with a clear message when the optional Python step is requested; keep controller-gen invocation in the generate target unchanged if deepcopy generation should remain independent of Python validation.deploy/operator/api/scripts/test_pydantic_models.py (1)
43-58: Tests usesys.exit(1)on first failure — later tests are never reached.Each test function calls
sys.exit(1)on any exception, which prevents subsequent tests from running and makes it harder to diagnose multiple issues at once. Consider collecting failures and reporting at the end, or usingpytest/unittestinstead of a custom runner.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@deploy/operator/api/scripts/test_pydantic_models.py` around lines 43 - 58, The test function test_simple_dgdr currently catches all exceptions and calls sys.exit(1), which aborts the test process and prevents subsequent tests from running; remove the try/except and sys.exit usage so failures surface normally (or re-raise the exception) and let the test framework (or a higher-level runner) report multiple failures, or convert this file to use pytest/unittest style asserts and test discovery for aggregated reporting; specifically modify test_simple_dgdr to not call sys.exit(1) on exception and instead allow the exception to propagate or use standard test framework patterns.deploy/operator/api/v1beta1/dynamographdeploymentrequest_types.go (2)
547-565: Minor: inconsistent receiver names across helper methods.
SetPhaseusesswhileGetPhase,SetProfilingPhase, andClearProfilingPhaseused. Consider unifying to a single name (e.g.,dfor "dgdr").🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@deploy/operator/api/v1beta1/dynamographdeploymentrequest_types.go` around lines 547 - 565, The receiver name in SetPhase is inconsistent (uses "s") compared to GetPhase, SetProfilingPhase, and ClearProfilingPhase which use "d"; update the SetPhase method receiver from "s *DynamoGraphDeploymentRequest" to "d *DynamoGraphDeploymentRequest" so all helper methods use the same receiver identifier (e.g., d) for DynamoGraphDeploymentRequest to improve consistency and readability.
569-579:AddStatusConditionreimplementsmeta.SetStatusConditionwithoutLastTransitionTimetracking.The standard
apimachinery/pkg/api/meta.SetStatusConditionautomatically preservesLastTransitionTimewhen the condition status hasn't changed and updates it when it has. This custom implementation replaces the condition unconditionally, which can causeLastTransitionTimeto be reset on every reconcile even when the condition hasn't changed.Proposed fix: use the standard helper
+import "k8s.io/apimachinery/pkg/api/meta" + // AddStatusCondition adds or updates a condition in the status. -// If a condition with the same type already exists, it replaces it. func (s *DynamoGraphDeploymentRequest) AddStatusCondition(condition metav1.Condition) { - if s.Status.Conditions == nil { - s.Status.Conditions = []metav1.Condition{} - } - for i, existing := range s.Status.Conditions { - if existing.Type == condition.Type { - s.Status.Conditions[i] = condition - return - } - } - s.Status.Conditions = append(s.Status.Conditions, condition) + meta.SetStatusCondition(&s.Status.Conditions, condition) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@deploy/operator/api/v1beta1/dynamographdeploymentrequest_types.go` around lines 569 - 579, The AddStatusCondition method on DynamoGraphDeploymentRequest reimplements condition replacement and therefore always overwrites LastTransitionTime; replace its logic to call the standard meta.SetStatusCondition helper so LastTransitionTime is preserved/updated correctly for s.Status.Conditions and metav1.Condition updates—i.e., import apimachinery/pkg/api/meta (meta) if needed and invoke meta.SetStatusCondition(&s.Status, condition) inside the AddStatusCondition method instead of the manual loop and append.components/src/dynamo/profiler/utils/dgdr_v1beta1_types.py (2)
321-325: Auto-generated docstring contains lifecycle steps instead of type description.The
DynamoGraphDeploymentRequestclass docstring is the lifecycle steps from the Go comment block rather than a description of what the class is. Consider improving the generator to extract the main description separately.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/src/dynamo/profiler/utils/dgdr_v1beta1_types.py` around lines 321 - 325, The class docstring for DynamoGraphDeploymentRequest currently contains lifecycle steps (Go comment block) instead of a concise type description; update the docstring to describe the purpose and contents of the DynamoGraphDeploymentRequest model (e.g., that it represents a request with optional spec and status fields), and remove or relocate the lifecycle steps to a more appropriate place (such as a separate constant, comment above the status enum/type, or the DynamoGraphDeploymentRequestStatus class) so the generated docstring is a clear human-readable type description for DynamoGraphDeploymentRequest (referencing the spec: DynamoGraphDeploymentRequestSpec and status: DynamoGraphDeploymentRequestStatus members).
110-113:pvcMountPathdefault differs from Go type.The Go type has
+kubebuilder:default="/opt/model-cache"but the generated Pydantic model defaults toNone. If the profiler relies on this default, objects constructed withoutpvcMountPathwill behave differently depending on whether they're created via Go or Python. Consider aligning the default:pvcMountPath: Optional[str] = Field( - default=None, + default="/opt/model-cache", description="PVCMountPath is the mount path for the PVC inside the container.", )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/src/dynamo/profiler/utils/dgdr_v1beta1_types.py` around lines 110 - 113, The pvcMountPath Field in dgdr_v1beta1_types.py currently defaults to None but must match the Go kubebuilder default "/opt/model-cache"; update the pvcMountPath declaration so its Field default is "/opt/model-cache" (i.e., change the default parameter on the Field for pvcMountPath) so Python-constructed objects have the same default as the Go type.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@components/src/dynamo/profiler/utils/dgdr_v1beta1_types.py`:
- Around line 1-8: Add the missing copyright/license header to the top of the
generated Pydantic file (dgdr_v1beta1_types.py) so CI's copyright check passes;
update the generator script generate_pydantic_from_go.py to prepend the same
header text it uses for test files (or a shared header template) when emitting
the file, ensuring the header appears before the auto-generated notice and file
content and is applied consistently for all generated outputs.
In `@deploy/operator/api/scripts/generate_pydantic_from_go.py`:
- Around line 1-10: Add the required NVIDIA SPDX copyright header to the top of
generate_pydantic_from_go.py (above the shebang or immediately after it if
policy requires) to satisfy CI; update the file header block so it includes the
standard SPDX-License-Identifier and copyright notice used across the repo,
ensuring the header appears before any module docstring or code in the
generate_pydantic_from_go.py script.
- Around line 190-210: The parser currently skips single-line comments
immediately preceding a field because of the conditional that checks a comment
line whose next line is not a comment; remove that premature skip so single-line
comments are not dropped and let the existing multi-line comment collector (the
while line.startswith("//") loop that fills comment_lines) handle both single-
and multi-line comment blocks for fields. Concretely, remove the entire if
branch that checks line.startswith("//") and i+1... (the guard before the
comment_lines collection) so the code always falls into the comment_lines
collection, and ensure i is still advanced correctly inside the collector to
avoid an infinite loop.
In `@deploy/operator/api/scripts/test_pydantic_models.py`:
- Around line 78-81: The test uses ModelCacheSpec with an invalid field name
pvcPath which Pydantic will ignore; update the instantiation to use the correct
field name pvcModelPath in the ModelCacheSpec call (replace
pvcPath="llama-3.1-405b" with pvcModelPath="llama-3.1-405b"), and add an
assertion like assert spec.modelCache.pvcModelPath == "llama-3.1-405b" to ensure
the value is actually set.
- Line 1: Add the required SPDX copyright header to the top of the script so the
CI copyright check passes: insert the standard SPDX header comment block
immediately after (or on the line following) the existing shebang in
deploy/operator/api/scripts/test_pydantic_models.py; ensure it uses the
project's expected format (e.g., an SPDX-License-Identifier line and copyright
notice) and preserves the shebang and file permissions.
In `@deploy/operator/api/v1alpha1/dynamographdeploymentrequest_conversion.go`:
- Around line 596-607: The fallback that builds a minimal DeploymentStatus when
dst.Deployment is nil and src.DGDName is set should not assume the DGD already
exists; change the constructed DeploymentStatus (currently
DeploymentStatus{Name: src.DGDName, Created: true}) to leave Created false (or
explicitly set Created: false) so the v1alpha1 controller will not skip creating
the DGD; update the block that assigns dst.Deployment when dst.Deployment == nil
&& src.DGDName != "" to use Created: false (or the zero value) and keep the Name
populated.
- Around line 163-164: The annDGDRProfilingJobName constant is declared but
never used, so Status.ProfilingJobName is not preserved across conversions;
update convertDGDRStatusFrom to read ProfilingJobName from the v1beta1 source
object's annotations using annDGDRProfilingJobName and set it into the v1alpha1
Status (or into ObjectMeta annotations on the target if the v1alpha1 Status
lacks the field), and update convertDGDRStatusTo to write ProfilingJobName back
into the v1beta1 target's annotations using annDGDRProfilingJobName when present
in the v1alpha1 source; use the existing annDGDRProfilingJobName symbol and the
convertDGDRStatusFrom/convertDGDRStatusTo functions to locate where to add the
read/write annotation logic so the value round-trips.
In `@deploy/operator/cmd/main.go`:
- Around line 127-128: The DGDR conversion webhook is not registered and the CRD
lacks a .spec.conversion section; update the CRD manifest to include a
.spec.conversion block (strategy: Webhook, webhookClientConfig pointing to the
operator service/URL with caBundle and conversionReviewVersions) and in main.go
register the conversion webhook handler alongside the existing
validation/defaulting webhooks (where
utilruntime.Must(nvidiacomv1beta1.AddToScheme(scheme)) and the
validation/defaulting SetupWebhookWithManager calls live). Ensure the
registration hooks connect to the types that implement Hub(), ConvertTo(), and
ConvertFrom() so the conversion webhook endpoint is exposed to the API server.
In `@docs/pages/kubernetes/api-reference.md`:
- Around line 1169-1176: The v1beta1 section generates headings that duplicate
anchors from v1alpha1 (e.g., DynamoGraphDeploymentRequest,
DynamoGraphDeploymentRequestSpec, DynamoGraphDeploymentRequestStatus) causing
links like [DynamoGraphDeploymentRequest](`#dynamographdeploymentrequest`) to
point to v1alpha1; update the documentation generator/template that emits these
headings so anchors are made unique (for example prepend the API group/version
to headings or anchors such as v1beta1-DynamoGraphDeploymentRequest or include
“v1beta1” in the visible heading text) so references in the v1beta1 block
resolve to the correct section.
---
Nitpick comments:
In `@components/src/dynamo/profiler/utils/dgdr_v1beta1_types.py`:
- Around line 321-325: The class docstring for DynamoGraphDeploymentRequest
currently contains lifecycle steps (Go comment block) instead of a concise type
description; update the docstring to describe the purpose and contents of the
DynamoGraphDeploymentRequest model (e.g., that it represents a request with
optional spec and status fields), and remove or relocate the lifecycle steps to
a more appropriate place (such as a separate constant, comment above the status
enum/type, or the DynamoGraphDeploymentRequestStatus class) so the generated
docstring is a clear human-readable type description for
DynamoGraphDeploymentRequest (referencing the spec:
DynamoGraphDeploymentRequestSpec and status: DynamoGraphDeploymentRequestStatus
members).
- Around line 110-113: The pvcMountPath Field in dgdr_v1beta1_types.py currently
defaults to None but must match the Go kubebuilder default "/opt/model-cache";
update the pvcMountPath declaration so its Field default is "/opt/model-cache"
(i.e., change the default parameter on the Field for pvcMountPath) so
Python-constructed objects have the same default as the Go type.
In `@deploy/operator/api/scripts/generate_pydantic_from_go.py`:
- Around line 396-406: The default for the --output argument in
parser.add_argument inside generate_pydantic_from_go.py is brittle because it
uses five successive Path.parent traversals to reach the repo path; replace this
with a robust repo-root resolution strategy (e.g., call out to git rev-parse
--show-toplevel or walk upward looking for a sentinel like go.mod) and build the
output Path relative to that root instead of chaining parent() calls; add a
helper function (e.g., resolve_repo_root or find_sentinel_root) and use it when
constructing the default for the --output argument so restructuring the repo
won’t change where dgdr_v1beta1_types.py is written.
- Around line 54-67: TYPE_MAP is a mutable module-level dict flagged by Ruff
RUF012; either annotate it as an immutable ClassVar typing or expose it as an
immutable mapping. Fix by adding a typing annotation (e.g., from typing import
ClassVar, Dict, Any; declare TYPE_MAP: ClassVar[Dict[str, Any]] = {...}) or wrap
the literal with types.MappingProxyType (import types and set TYPE_MAP =
types.MappingProxyType({...})), and update imports accordingly so TYPE_MAP is
read-only at runtime.
In `@deploy/operator/api/scripts/test_pydantic_models.py`:
- Around line 43-58: The test function test_simple_dgdr currently catches all
exceptions and calls sys.exit(1), which aborts the test process and prevents
subsequent tests from running; remove the try/except and sys.exit usage so
failures surface normally (or re-raise the exception) and let the test framework
(or a higher-level runner) report multiple failures, or convert this file to use
pytest/unittest style asserts and test discovery for aggregated reporting;
specifically modify test_simple_dgdr to not call sys.exit(1) on exception and
instead allow the exception to propagate or use standard test framework
patterns.
In `@deploy/operator/api/v1beta1/dynamographdeploymentrequest_types.go`:
- Around line 547-565: The receiver name in SetPhase is inconsistent (uses "s")
compared to GetPhase, SetProfilingPhase, and ClearProfilingPhase which use "d";
update the SetPhase method receiver from "s *DynamoGraphDeploymentRequest" to "d
*DynamoGraphDeploymentRequest" so all helper methods use the same receiver
identifier (e.g., d) for DynamoGraphDeploymentRequest to improve consistency and
readability.
- Around line 569-579: The AddStatusCondition method on
DynamoGraphDeploymentRequest reimplements condition replacement and therefore
always overwrites LastTransitionTime; replace its logic to call the standard
meta.SetStatusCondition helper so LastTransitionTime is preserved/updated
correctly for s.Status.Conditions and metav1.Condition updates—i.e., import
apimachinery/pkg/api/meta (meta) if needed and invoke
meta.SetStatusCondition(&s.Status, condition) inside the AddStatusCondition
method instead of the manual loop and append.
In `@deploy/operator/Makefile`:
- Around line 143-152: The generate target currently depends on
generate-pydantic making python3 and pydantic required for make generate; change
this by removing generate-pydantic from the generate prerequisites and either
(A) add a new independent opt-in target (e.g., generate-pydantic) users run
manually, or (B) introduce a guard target ensure-python (similar to ensure-yq)
that checks for python3 and that pydantic can be imported (e.g., using command
-v python3 and python3 -c "import pydantic") and make generate-pydantic depend
on ensure-python so generation only fails with a clear message when the optional
Python step is requested; keep controller-gen invocation in the generate target
unchanged if deepcopy generation should remain independent of Python validation.
|
/ok to test a38e026 |
Signed-off-by: Hannah Zhang <hannahz@nvidia.com>
|
/ok to test 3ff1e32 |
Signed-off-by: Hannah Zhang <hannahz@nvidia.com>
…feature-add-conversion-from-dgdr-v1alpha1-to-dgdr-v1beta1
|
/ok to test c51b73c |
Signed-off-by: Hannah Zhang <hannahz@nvidia.com>
|
/ok to test 3b56cf9 |
Signed-off-by: Hannah Zhang <hannahz@nvidia.com>
|
/ok to test ed1112b |
Signed-off-by: Hannah Zhang <hannahz@nvidia.com>
|
/ok to test a6d2f5a |
dmitry-tokarev-nv
left a comment
There was a problem hiding this comment.
python 3.11 is a bit behind. We use 3.12. but it works for this job
Signed-off-by: Jont828 <jt572@cornell.edu> Signed-off-by: Hongkuan Zhou <hongkuanz@nvidia.com> Signed-off-by: Hannah Zhang <hannahz@nvidia.com> Co-authored-by: Jont828 <jt572@cornell.edu>
Overview:
This MR adds the v1beta1 DGDR API laid out in ai-dynamo/enhancements#62 with conversion from the v1alpha1 DGDR schema, as well as automatic conversion into a Python Pydantic class for Dynamo Profiler.
Details:
Continuation of #6130, with conversion scripts. Follows k8s convention, with a hub/Spoke pattern: v1beta1 as hub, v1alpha1 as spoke. Most fields are mapped over, with any v1alpha1-specific fields preserved thru annotations. Marked v1alpha1 as deprecated while maintaining full backward compatibility with automatic conversion and user warnings. All fields have comprehensive comments/documentation.
Also added a script for automatic Pydantic model generation from Go types, for the Dynamo Profiler. Handles type mapping and structs/enums. Integrated this generation into
buildto keep things cohesive/so things don't break --make generateruns generation + tests automatically.Where should the reviewer start?
Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)
Summary by CodeRabbit
New Features
Deprecation
Documentation