summaryrefslogtreecommitdiff
path: root/Omni/Agent/Prompts
diff options
context:
space:
mode:
Diffstat (limited to 'Omni/Agent/Prompts')
-rw-r--r--Omni/Agent/Prompts/Cli.hs110
1 files changed, 110 insertions, 0 deletions
diff --git a/Omni/Agent/Prompts/Cli.hs b/Omni/Agent/Prompts/Cli.hs
new file mode 100644
index 0000000..c0a792f
--- /dev/null
+++ b/Omni/Agent/Prompts/Cli.hs
@@ -0,0 +1,110 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+-- | CLI tool for previewing and debugging prompt templates.
+--
+-- Usage:
+-- omni-agent-prompt list
+-- omni-agent-prompt agents/telegram/system
+-- omni-agent-prompt subagents/coder/system --var namespace=Omni/Jr --var task="Add feature"
+-- omni-agent-prompt subagents/generic/system --json '{"task":"Research X","role_description":"research"}'
+--
+-- : out omni-agent-prompt
+-- : dep aeson
+-- : dep bytestring
+-- : dep text
+-- : dep mustache
+-- : dep unordered-containers
+module Omni.Agent.Prompts.Cli (main) where
+
+import Alpha
+import qualified Data.Aeson as Aeson
+import qualified Data.Aeson.Key as Key
+import qualified Data.Aeson.KeyMap as KeyMap
+import qualified Data.ByteString.Lazy as BL
+import qualified Data.Text as Text
+import qualified Data.Text.Encoding as TE
+import qualified Data.Text.IO as TextIO
+import qualified Omni.Agent.Prompts as Prompts
+import qualified System.Environment as Env
+import qualified System.Exit as Exit
+
+main :: IO ()
+main = do
+ args <- Env.getArgs
+ case args of
+ [] -> usage
+ ["--help"] -> usage
+ ["-h"] -> usage
+ ["list"] -> listPrompts
+ (pid : rest) -> renderPromptCmd (Text.pack pid) rest
+
+usage :: IO ()
+usage = do
+ putText "omni-agent-prompt - Preview and debug prompt templates"
+ putText ""
+ putText "Usage:"
+ putText " omni-agent-prompt list"
+ putText " omni-agent-prompt <prompt-id> [--var key=value]... [--json '{...}']"
+ putText ""
+ putText "Examples:"
+ putText " omni-agent-prompt agents/telegram/system"
+ putText " omni-agent-prompt subagents/coder/system --var namespace=Omni/Jr --var task='Add feature'"
+ putText " omni-agent-prompt subagents/generic/system --json '{\"task\":\"Research X\"}'"
+ putText ""
+ putText <| "Prompts directory: " <> Text.pack Prompts.promptsDir
+
+listPrompts :: IO ()
+listPrompts = do
+ prompts <- Prompts.listPrompts
+ if null prompts
+ then do
+ putText "No prompts found."
+ putText <| "Prompts directory: " <> Text.pack Prompts.promptsDir
+ else do
+ putText "Available prompts:"
+ putText ""
+ forM_ prompts <| \(pid, meta) -> do
+ let desc = fromMaybe "" (Prompts.pmDescription meta)
+ if Text.null desc
+ then putText <| " " <> pid
+ else putText <| " " <> pid <> " - " <> desc
+
+renderPromptCmd :: Text -> [String] -> IO ()
+renderPromptCmd pid args = do
+ let (jsonCtx, kvPairs) = parseArgs args
+ ctx <- case jsonCtx of
+ Nothing -> pure <| buildContext kvPairs
+ Just jsonStr -> case Aeson.decode (BL.fromStrict (TE.encodeUtf8 jsonStr)) of
+ Nothing -> do
+ putText <| "Error: Invalid JSON: " <> jsonStr
+ Exit.exitFailure
+ Just obj -> pure <| mergeContext obj kvPairs
+
+ result <- Prompts.renderPrompt pid ctx
+ case result of
+ Left err -> do
+ putText <| "Error: " <> err
+ Exit.exitFailure
+ Right rendered -> TextIO.putStrLn rendered
+
+parseArgs :: [String] -> (Maybe Text, [(Text, Text)])
+parseArgs = go Nothing []
+ where
+ go json kvs [] = (json, reverse kvs)
+ go _json kvs ("--json" : val : rest) = go (Just (Text.pack val)) kvs rest
+ go json kvs ("--var" : kv : rest) =
+ case Text.breakOn "=" (Text.pack kv) of
+ (k, v)
+ | not (Text.null v) -> go json ((k, Text.drop 1 v) : kvs) rest
+ | otherwise -> go json kvs rest
+ go json kvs (_ : rest) = go json kvs rest
+
+buildContext :: [(Text, Text)] -> Aeson.Value
+buildContext kvs =
+ Aeson.Object <| KeyMap.fromList [(Key.fromText k, Aeson.String v) | (k, v) <- kvs]
+
+mergeContext :: Aeson.Value -> [(Text, Text)] -> Aeson.Value
+mergeContext (Aeson.Object obj) kvs =
+ Aeson.Object <| foldr (\(k, v) m -> KeyMap.insert (Key.fromText k) (Aeson.String v) m) obj kvs
+mergeContext _ kvs = buildContext kvs