never executed always true always false
    1 module PureClaw.Tools.Message
    2   ( -- * Tool registration
    3     messageTool
    4   ) where
    5 
    6 import Control.Exception
    7 import Data.Aeson
    8 import Data.Aeson.Types
    9 import Data.Text (Text)
   10 import Data.Text qualified as T
   11 
   12 import PureClaw.Handles.Channel
   13 import PureClaw.Providers.Class
   14 import PureClaw.Tools.Registry
   15 
   16 -- | Create a message tool for proactive agent-initiated messaging.
   17 -- Sends a message to the active channel (Signal, Telegram, CLI, etc.).
   18 -- Used for cron results, alerts, and notifications.
   19 messageTool :: ChannelHandle -> (ToolDefinition, ToolHandler)
   20 messageTool ch = (def, handler)
   21   where
   22     def = ToolDefinition
   23       { _td_name        = "message"
   24       , _td_description = "Send a proactive message to the user via the active channel. Use for alerts, cron results, and notifications."
   25       , _td_inputSchema = object
   26           [ "type" .= ("object" :: Text)
   27           , "properties" .= object
   28               [ "content" .= object
   29                   [ "type" .= ("string" :: Text)
   30                   , "description" .= ("The message content to send" :: Text)
   31                   ]
   32               ]
   33           , "required" .= (["content"] :: [Text])
   34           ]
   35       }
   36 
   37     handler = ToolHandler $ \input ->
   38       case parseEither parseInput input of
   39         Left err -> pure (T.pack err, True)
   40         Right content
   41           | T.null (T.strip content) -> pure ("Empty message", True)
   42           | otherwise -> do
   43               result <- try @SomeException
   44                 (_ch_send ch (OutgoingMessage content))
   45               case result of
   46                 Left e -> pure (T.pack (show e), True)
   47                 Right () -> pure ("Message sent", False)
   48 
   49     parseInput :: Value -> Parser Text
   50     parseInput = withObject "MessageInput" $ \o -> o .: "content"