code: def add(self, annotation: ArtifactDescribeAnnotation, name: str):
      if name in self._keys:
          raise ValueError(f"artifact {name} already exists")
      self._keys.add(name)
      if annotation.is_input:
          if annotation.describe_type_kind == "data":
              self.data_inputs[name] = annotation.apply(name)
          elif annotation.describe_type_kind == "model":
              self.model_inputs[name] = annotation.apply(name)
          else:
              raise ValueError(
                  f"unknown artifact type {annotation.describe_type_kind}"
              )
      else:
          if annotation.describe_type_kind == "data":
              self.data_outputs[name] = annotation.apply(name)
          elif annotation.describe_type_kind == "model":
              self.model_outputs[name] = annotation.apply(name)
          elif annotation.describe_type_kind == "metric":
              self.metric_outputs[name] = annotation.apply(name)
          else:
              raise ValueError(
                  f"unknown artifact type {annotation.describe_type_kind}"
              )
  
imports: import typing
  from typing import Dict, List, Type, Union
label_desc: Use image node_id 3 for calling the ComponentArtifactDescribes obj's underlying member method code with example usage: obj.add(annotation, name) without return types