2525import inspect
2626import re
2727from collections .abc import Awaitable , Callable
28- from typing import Any , Protocol , TypedDict
28+ from typing import Any , Protocol , TypedDict , cast
2929
3030from pydantic import BaseModel
3131
@@ -88,6 +88,12 @@ def __call__(self, input: ResourceInput, ctx: ActionRunContext) -> Awaitable[Res
8888 ...
8989
9090
91+ class MatchableAction (Protocol ):
92+ """Protocol for actions that have a matches method."""
93+
94+ matches : Callable [[ResourceInput ], bool ]
95+
96+
9197ResourceArgument = Action | str
9298
9399
@@ -136,9 +142,9 @@ async def lookup_resource_by_name(registry: Registry, name: str) -> Action:
136142 ValueError: If the resource cannot be found.
137143 """
138144 resource = (
139- await registry .resolve_action (ActionKind .RESOURCE , name )
140- or await registry .resolve_action (ActionKind .RESOURCE , f'/resource/{ name } ' )
141- or await registry .resolve_action (ActionKind .RESOURCE , f'/dynamic-action-provider/{ name } ' )
145+ await registry .resolve_action (cast ( ActionKind , ActionKind .RESOURCE ) , name )
146+ or await registry .resolve_action (cast ( ActionKind , ActionKind .RESOURCE ) , f'/resource/{ name } ' )
147+ or await registry .resolve_action (cast ( ActionKind , ActionKind .RESOURCE ) , f'/dynamic-action-provider/{ name } ' )
142148 )
143149 if not resource :
144150 raise ValueError (f'Resource { name } not found' )
@@ -161,7 +167,7 @@ def define_resource(registry: Registry, opts: ResourceOptions, fn: ResourceFn) -
161167 """
162168 action = dynamic_resource (opts , fn )
163169
164- action .matches = create_matcher (opts .get ('uri' ), opts .get ('template' ))
170+ cast ( MatchableAction , action ) .matches = create_matcher (opts .get ('uri' ), opts .get ('template' ))
165171
166172 # Mark as not dynamic since it's being registered
167173 action .metadata ['dynamic' ] = False
@@ -279,7 +285,7 @@ async def wrapped_fn(input_data: ResourceInput, ctx: ActionRunContext) -> Resour
279285
280286 act = Action (
281287 name = name ,
282- kind = ActionKind .RESOURCE ,
288+ kind = cast ( ActionKind , ActionKind .RESOURCE ) ,
283289 fn = wrapped_fn ,
284290 metadata = {
285291 'resource' : {
@@ -291,7 +297,7 @@ async def wrapped_fn(input_data: ResourceInput, ctx: ActionRunContext) -> Resour
291297 description = opts .get ('description' ),
292298 span_metadata = {'genkit:metadata:resource:uri' : uri },
293299 )
294- act .matches = matcher
300+ cast ( MatchableAction , act ) .matches = matcher
295301 return act
296302
297303
@@ -385,23 +391,27 @@ async def find_matching_resource(
385391 """
386392 if dynamic_resources :
387393 for action in dynamic_resources :
388- if hasattr (action , 'matches' ) and action .matches (input_data ):
394+ if hasattr (action , 'matches' ) and cast ( MatchableAction , action ) .matches (input_data ):
389395 return action
390396
391397 # Try exact match in registry
392- resource = await registry .resolve_action (ActionKind .RESOURCE , input_data .uri )
398+ resource = await registry .resolve_action (cast ( ActionKind , ActionKind .RESOURCE ) , input_data .uri )
393399 if resource :
394400 return resource
395401
396402 # Iterate all resources to check for matches (e.g. templates)
397403 # This is less efficient but necessary for template matching if not optimized
398- resources = registry .get_actions_by_kind (ActionKind .RESOURCE ) if hasattr (registry , 'get_actions_by_kind' ) else {}
404+ resources = (
405+ registry .get_actions_by_kind (cast (ActionKind , ActionKind .RESOURCE ))
406+ if hasattr (registry , 'get_actions_by_kind' )
407+ else {}
408+ )
399409 if not resources and hasattr (registry , '_entries' ):
400410 # Fallback for compatibility if registry instance is old (unlikely in this context)
401- resources = registry ._entries .get (ActionKind .RESOURCE , {})
411+ resources = registry ._entries .get (cast ( ActionKind , ActionKind .RESOURCE ) , {})
402412
403413 for action in resources .values ():
404- if hasattr (action , 'matches' ) and action .matches (input_data ):
414+ if hasattr (action , 'matches' ) and cast ( MatchableAction , action ) .matches (input_data ):
405415 return action
406416
407417 return None
0 commit comments