1- from typing import ClassVar , Literal , Annotated , Optional
2- from pydantic import RootModel , model_serializer , SerializerFunctionWrapHandler , SerializationInfo , Field
1+ from typing import ClassVar
2+ from pydantic import RootModel , model_serializer , SerializerFunctionWrapHandler , SerializationInfo
33from core .enums import ResourceCategory
44
55
66class Ref (RootModel [str ]):
77 """
8+ Base class for resource references.
9+
810 A wrapper around a single string that may be:
911 - a bare ID, e.g. "abcd-1234"
1012 - an external ref, e.g. "$ref:abcd-1234"
1113
12- Exposes:
13- - .root the original string
14- - .ref the ID without prefix
15- - .is_external_ref()
16- - .is_inline()
17- - .get_category() NEW: get resource category
14+ All subclasses MUST define _category to specify which resource
15+ category they reference. This is enforced at class definition time.
1816 """
1917 REF_PREFIX : ClassVar [str ] = "$ref:"
20- _category : ClassVar [Optional [ResourceCategory ]] = None
18+ _category : ClassVar [ResourceCategory ]
19+
20+ def __init_subclass__ (cls , ** kwargs ):
21+ """Enforce that all Ref subclasses define _category."""
22+ super ().__init_subclass__ (** kwargs )
23+ if not hasattr (cls , '_category' ) or cls ._category is None :
24+ raise TypeError (
25+ f"Ref subclass '{ cls .__name__ } ' must define '_category'. "
26+ f"Example: _category: ClassVar[ResourceCategory] = ResourceCategory.YOUR_CATEGORY"
27+ )
2128
2229 @property
2330 def ref (self ) -> str :
31+ """The ID without the $ref: prefix."""
2432 raw = self .root
2533 if raw .startswith (self .REF_PREFIX ):
2634 return raw [len (self .REF_PREFIX ):]
@@ -31,10 +39,10 @@ def is_external_ref(self) -> bool:
3139
3240 def is_inline (self ) -> bool :
3341 return not self .is_external_ref ()
34-
35- def get_category (self ) -> Optional [ ResourceCategory ] :
42+
43+ def get_category (self ) -> ResourceCategory :
3644 """Get the resource category this ref points to."""
37- return getattr ( self .__class__ , ' _category' , None )
45+ return self ._category
3846
3947 @model_serializer (mode = "wrap" )
4048 def _serialize (self , handler : SerializerFunctionWrapHandler , info : SerializationInfo ) -> str :
@@ -47,11 +55,10 @@ def _serialize(self, handler: SerializerFunctionWrapHandler, info: Serialization
4755 return self .ref
4856
4957
50- # Specific Ref classes with category information + JSON schema
5158class LLMRef (Ref ):
5259 """Reference to an LLM resource."""
5360 _category : ClassVar [ResourceCategory ] = ResourceCategory .LLM
54-
61+
5562 model_config = {
5663 "json_schema_extra" : {
5764 "category" : ResourceCategory .LLM .value ,
@@ -64,11 +71,11 @@ class LLMRef(Ref):
6471class NodeRef (Ref ):
6572 """Reference to a Node resource."""
6673 _category : ClassVar [ResourceCategory ] = ResourceCategory .NODE
67-
74+
6875 model_config = {
6976 "json_schema_extra" : {
7077 "category" : ResourceCategory .NODE .value ,
71- "description" : "Reference to a Node resource" ,
78+ "description" : "Reference to a Node resource" ,
7279 "examples" : ["$ref:custom-agent-1" , "data-processor" ]
7380 }
7481 }
@@ -77,7 +84,7 @@ class NodeRef(Ref):
7784class RetrieverRef (Ref ):
7885 """Reference to a Retriever resource."""
7986 _category : ClassVar [ResourceCategory ] = ResourceCategory .RETRIEVER
80-
87+
8188 model_config = {
8289 "json_schema_extra" : {
8390 "category" : ResourceCategory .RETRIEVER .value ,
@@ -90,7 +97,7 @@ class RetrieverRef(Ref):
9097class ToolRef (Ref ):
9198 """Reference to a Tool resource."""
9299 _category : ClassVar [ResourceCategory ] = ResourceCategory .TOOL
93-
100+
94101 model_config = {
95102 "json_schema_extra" : {
96103 "category" : ResourceCategory .TOOL .value ,
@@ -103,7 +110,7 @@ class ToolRef(Ref):
103110class ProviderRef (Ref ):
104111 """Reference to a Provider resource."""
105112 _category : ClassVar [ResourceCategory ] = ResourceCategory .PROVIDER
106-
113+
107114 model_config = {
108115 "json_schema_extra" : {
109116 "category" : ResourceCategory .PROVIDER .value ,
@@ -116,7 +123,7 @@ class ProviderRef(Ref):
116123class ConditionRef (Ref ):
117124 """Reference to a Condition resource."""
118125 _category : ClassVar [ResourceCategory ] = ResourceCategory .CONDITION
119-
126+
120127 model_config = {
121128 "json_schema_extra" : {
122129 "category" : ResourceCategory .CONDITION .value ,
0 commit comments