2323"""
2424
2525from collections .abc import Callable
26- from typing import Generic , TypeVar
26+ from typing import Any , Generic , TypeVar
27+
28+ from pydantic import BaseModel , ConfigDict , Field
2729
2830from genkit .blocks .document import Document
29- from genkit .core .typing import RetrieverResponse
31+ from genkit .core .action import ActionMetadata
32+ from genkit .core .action .types import ActionKind
33+ from genkit .core .schema import to_json_schema
34+ from genkit .core .typing import DocumentData , RetrieverResponse
3035
3136T = TypeVar ('T' )
3237# type RetrieverFn[T] = Callable[[Document, T], RetrieverResponse]
@@ -39,3 +44,201 @@ def __init__(
3944 retriever_fn : RetrieverFn [T ],
4045 ):
4146 self .retriever_fn = retriever_fn
47+
48+
49+ class RetrieverRequest (BaseModel ):
50+ model_config = ConfigDict (extra = 'forbid' , populate_by_name = True )
51+
52+ query : DocumentData
53+ options : Any | None = None
54+
55+
56+ class RetrieverSupports (BaseModel ):
57+ """Retriever capability support."""
58+
59+ model_config = ConfigDict (extra = 'forbid' , populate_by_name = True )
60+
61+ media : bool | None = None
62+
63+
64+ class RetrieverInfo (BaseModel ):
65+ model_config = ConfigDict (extra = 'forbid' , populate_by_name = True )
66+
67+ label : str | None = None
68+ supports : RetrieverSupports | None = None
69+
70+
71+ class RetrieverOptions (BaseModel ):
72+ """Configuration options for a retriever."""
73+
74+ model_config = ConfigDict (extra = 'forbid' , populate_by_name = True )
75+
76+ config_schema : dict [str , Any ] | None = Field (None , alias = 'configSchema' )
77+ label : str | None = None
78+ supports : RetrieverSupports | None = None
79+
80+
81+ class RetrieverRef (BaseModel ):
82+ """Reference to a retriever with configuration."""
83+
84+ model_config = ConfigDict (extra = 'forbid' , populate_by_name = True )
85+
86+ name : str
87+ config : Any | None = None
88+ version : str | None = None
89+ info : RetrieverInfo | None = None
90+
91+
92+ def retriever_action_metadata (
93+ name : str ,
94+ options : RetrieverOptions | None = None ,
95+ ) -> ActionMetadata :
96+ """Creates action metadata for a retriever."""
97+ options = options if options is not None else RetrieverOptions ()
98+ retriever_metadata_dict = {'retriever' : {}}
99+
100+ if options .label :
101+ retriever_metadata_dict ['retriever' ]['label' ] = options .label
102+
103+ if options .supports :
104+ retriever_metadata_dict ['retriever' ]['supports' ] = options .supports .model_dump (exclude_none = True , by_alias = True )
105+
106+ retriever_metadata_dict ['retriever' ]['customOptions' ] = options .config_schema if options .config_schema else None
107+
108+ return ActionMetadata (
109+ kind = ActionKind .RETRIEVER ,
110+ name = name ,
111+ input_json_schema = to_json_schema (RetrieverRequest ),
112+ output_json_schema = to_json_schema (RetrieverResponse ),
113+ metadata = retriever_metadata_dict ,
114+ )
115+
116+
117+ def create_retriever_ref (
118+ name : str ,
119+ config : dict [str , Any ] | None = None ,
120+ version : str | None = None ,
121+ info : RetrieverInfo | None = None ,
122+ ) -> RetrieverRef :
123+ """Creates a RetrieverRef instance."""
124+ return RetrieverRef (name = name , config = config , version = version , info = info )
125+
126+
127+ class IndexerRequest (BaseModel ):
128+ model_config = ConfigDict (extra = 'forbid' , populate_by_name = True )
129+
130+ documents : list [DocumentData ]
131+ options : Any | None = None
132+
133+
134+ class IndexerInfo (BaseModel ):
135+ model_config = ConfigDict (extra = 'forbid' , populate_by_name = True )
136+
137+ label : str | None = None
138+ supports : RetrieverSupports | None = None
139+
140+
141+ class IndexerOptions (BaseModel ):
142+ model_config = ConfigDict (extra = 'forbid' , populate_by_name = True )
143+
144+ config_schema : dict [str , Any ] | None = Field (None , alias = 'configSchema' )
145+ label : str | None = None
146+ supports : RetrieverSupports | None = None
147+
148+
149+ class IndexerRef (BaseModel ):
150+ """Reference to an indexer with configuration."""
151+
152+ model_config = ConfigDict (extra = 'forbid' , populate_by_name = True )
153+
154+ name : str
155+ config : Any | None = None
156+ version : str | None = None
157+ info : IndexerInfo | None = None
158+
159+
160+ def indexer_action_metadata (
161+ name : str ,
162+ options : IndexerOptions | None = None ,
163+ ) -> ActionMetadata :
164+ """Creates action metadata for an indexer."""
165+ options = options if options is not None else IndexerOptions ()
166+ indexer_metadata_dict = {'indexer' : {}}
167+
168+ if options .label :
169+ indexer_metadata_dict ['indexer' ]['label' ] = options .label
170+
171+ if options .supports :
172+ indexer_metadata_dict ['indexer' ]['supports' ] = options .supports .model_dump (exclude_none = True , by_alias = True )
173+
174+ indexer_metadata_dict ['indexer' ]['customOptions' ] = options .config_schema if options .config_schema else None
175+
176+ return ActionMetadata (
177+ kind = ActionKind .INDEXER ,
178+ name = name ,
179+ input_json_schema = to_json_schema (IndexerRequest ),
180+ output_json_schema = to_json_schema (None ),
181+ metadata = indexer_metadata_dict ,
182+ )
183+
184+
185+ def create_indexer_ref (
186+ name : str ,
187+ config : dict [str , Any ] | None = None ,
188+ version : str | None = None ,
189+ info : IndexerInfo | None = None ,
190+ ) -> IndexerRef :
191+ """Creates a IndexerRef instance."""
192+ return IndexerRef (name = name , config = config , version = version , info = info )
193+
194+
195+ def define_retriever (
196+ registry : Any ,
197+ name : str ,
198+ fn : RetrieverFn ,
199+ options : RetrieverOptions | None = None ,
200+ ) -> None :
201+ """Defines and registers a retriever action."""
202+ metadata = retriever_action_metadata (name , options )
203+
204+ async def wrapper (
205+ request : RetrieverRequest ,
206+ ctx : Any ,
207+ ) -> RetrieverResponse :
208+ return await fn (request .query , request .options )
209+
210+ registry .register_action (
211+ kind = ActionKind .RETRIEVER ,
212+ name = name ,
213+ fn = wrapper ,
214+ metadata = metadata .metadata ,
215+ span_metadata = metadata .metadata ,
216+ )
217+
218+
219+ IndexerFn = Callable [[list [Document ], T ], None ]
220+
221+
222+ def define_indexer (
223+ registry : Any ,
224+ name : str ,
225+ fn : IndexerFn ,
226+ options : IndexerOptions | None = None ,
227+ ) -> None :
228+ """Defines and registers an indexer action."""
229+ metadata = indexer_action_metadata (name , options )
230+
231+ async def wrapper (
232+ request : IndexerRequest ,
233+ ctx : Any ,
234+ ) -> None :
235+ docs = [Document .from_data (d ) for d in request .documents ]
236+ await fn (docs , request .options )
237+
238+ registry .register_action (
239+ kind = ActionKind .INDEXER ,
240+ name = name ,
241+ fn = wrapper ,
242+ metadata = metadata .metadata ,
243+ span_metadata = metadata .metadata ,
244+ )
0 commit comments