never executed always true always false
    1 module PureClaw.Tools.Registry
    2   ( -- * Tool execution
    3     ToolHandler (..)
    4   , ToolRegistry
    5     -- * Registry operations
    6   , emptyRegistry
    7   , registerTool
    8   , registerRichTool
    9   , registryDefinitions
   10   , executeTool
   11   ) where
   12 
   13 import Data.Aeson (Value)
   14 import Data.Map.Strict (Map)
   15 import Data.Map.Strict qualified as Map
   16 import Data.Text (Text)
   17 
   18 import PureClaw.Providers.Class
   19 
   20 -- | A tool handler: given JSON input, produce a text result.
   21 -- The Bool in the result indicates whether the result is an error.
   22 newtype ToolHandler = ToolHandler
   23   { runTool :: Value -> IO (Text, Bool)
   24   }
   25 
   26 -- | Registry of available tools. Maps tool names to their definitions
   27 -- and handlers that return rich content (text + images).
   28 newtype ToolRegistry = ToolRegistry
   29   { _tr_tools :: Map Text (ToolDefinition, Value -> IO ([ToolResultPart], Bool))
   30   }
   31 
   32 -- | Empty registry with no tools.
   33 emptyRegistry :: ToolRegistry
   34 emptyRegistry = ToolRegistry Map.empty
   35 
   36 -- | Register a text-only tool with its definition and handler.
   37 registerTool :: ToolDefinition -> ToolHandler -> ToolRegistry -> ToolRegistry
   38 registerTool def handler = registerRichTool def $ \v -> do
   39   (text, isErr) <- runTool handler v
   40   pure ([TRPText text], isErr)
   41 
   42 -- | Register a tool that returns rich content (text, images).
   43 registerRichTool :: ToolDefinition -> (Value -> IO ([ToolResultPart], Bool)) -> ToolRegistry -> ToolRegistry
   44 registerRichTool def handler reg = reg
   45   { _tr_tools = Map.insert (_td_name def) (def, handler) (_tr_tools reg)
   46   }
   47 
   48 -- | Get all tool definitions for sending to the provider.
   49 registryDefinitions :: ToolRegistry -> [ToolDefinition]
   50 registryDefinitions = map fst . Map.elems . _tr_tools
   51 
   52 -- | Execute a tool by name. Returns Nothing if the tool is not found.
   53 executeTool :: ToolRegistry -> Text -> Value -> IO (Maybe ([ToolResultPart], Bool))
   54 executeTool reg name input =
   55   case Map.lookup name (_tr_tools reg) of
   56     Nothing -> pure Nothing
   57     Just (_, handler) -> Just <$> handler input