Replies: 2 comments
-
While using pydantic, you likely have come across In Swarmauri we encountered a similar problem while trying to create polymorphic instances of Example of this is: class AccessibilityToolkit(ToolkitBase):
type: Literal["AccessibilityToolkit"] = "AccessibilityToolkit"
resource: str = "AccessibilityToolkit"
# Explicitly define the tools as fields
automated_readability_index_tool: AutomatedReadabilityIndexTool = Field(
default_factory=lambda: AutomatedReadabilityIndexTool(
name="AutomatedReadabilityIndexTool"
)
)
coleman_liau_index_tool: ColemanLiauIndexTool = Field(
default_factory=lambda: ColemanLiauIndexTool(name="ColemanLiauIndexTool")
)
flesch_kincaid_tool: FleschKincaidTool = Field(
default_factory=lambda: FleschKincaidTool(name="FleschKincaidTool")
)
flesch_reading_ease_tool: FleschReadingEaseTool = Field(
default_factory=lambda: FleschReadingEaseTool(name="FleschReadingEaseTool")
)
gunning_fog_tool: GunningFogTool = Field(
default_factory=lambda: GunningFogTool(name="GunningFogTool")
)
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Add all tools to the toolkit using add_tools method
self.add_tool(self.automated_readability_index_tool)
self.add_tool(self.coleman_liau_index_tool)
self.add_tool(self.flesch_kincaid_tool)
self.add_tool(self.flesch_reading_ease_tool)
self.add_tool(self.gunning_fog_tool) The During deserialization, pydantic was not correctly to determine the type of tool that is:
This type of errors show that the deserialization wasn't able to correctly figure out the Well, when this happens manual validation of the classes is required. The manual validation should satisfy flexibility in terms of adding new tools in the toolkit. Here is the solution used to solve the problem @model_validator(mode="wrap")
@classmethod
def validate_model(cls, values: Any, handler: Any):
# Extract the tools and validate their types manually
tools = values.get("tools", {})
for tool_name, tool_data in tools.items():
if isinstance(tool_data, dict):
tool_type = tool_data.get("type")
tool_id = tool_data.get("id") # Preserve the ID if it exists
try:
# Assuming SubclassUnion returns a dictionary or a list of tool classes
tool_class = next(
sc
for sc in SubclassUnion.__swm__get_subclasses__(ToolBase)
if sc.__name__ == tool_type
)
logging.info(tool_class)
# Create an instance of the tool class
tools[tool_name] = tool_class(**tool_data)
tools[
tool_name
].id = tool_id # Ensure the tool ID is not changed unintentionally
except StopIteration:
raise ValueError(f"Unknown tool type: {tool_type}")
values["tools"] = tools
return handler(values) The solution above provides the flexibility required by utilizing |
Beta Was this translation helpful? Give feedback.
-
This issue was fixed by PR https://github.com/swarmauri/swarmauri-sdk/pull/423 |
Beta Was this translation helpful? Give feedback.
-
Generic Concrete classes should be able to support polymorphism, including third party plug-ins.
This requires that typing be updated in the model JSON schema, annotations, and attribute definition.
Additionally this requires a mapping of type Literal to a reference of a Module in Memory.
Beta Was this translation helpful? Give feedback.
All reactions