summaryrefslogtreecommitdiff
path: root/Omni/Ava.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Omni/Ava.hs')
-rwxr-xr-xOmni/Ava.hs57
1 files changed, 52 insertions, 5 deletions
diff --git a/Omni/Ava.hs b/Omni/Ava.hs
index 0788658..3640fc2 100755
--- a/Omni/Ava.hs
+++ b/Omni/Ava.hs
@@ -9,19 +9,27 @@
-- ava # Uses TELEGRAM_BOT_TOKEN env var
-- ava --token=XXX # Explicit token
-- ava --model=MODEL # Override LLM model
+-- ava logs [--last=N] [SUBAGENT_ID] # View audit logs
--
-- : out ava
-- : dep aeson
-- : dep http-conduit
-- : dep stm
+-- : dep time
+-- : dep uuid
module Omni.Ava where
import Alpha
+import qualified Data.Aeson as Aeson
import qualified Data.Text as Text
+import qualified Data.Text.IO as TextIO
+import qualified Data.Time as Time
+import qualified Omni.Agent.AuditLog as AuditLog
import qualified Omni.Agent.Telegram as Telegram
import qualified Omni.Cli as Cli
import qualified Omni.Test as Test
import qualified System.Console.Docopt as Docopt
+import qualified System.Directory as Dir
import qualified System.IO as IO
main :: IO ()
@@ -43,21 +51,60 @@ ava - AI assistant via Telegram
Usage:
ava [--token=TOKEN] [--model=MODEL]
+ ava logs [--last=N] [<subagent_id>]
ava test
ava (-h | --help)
Options:
- -h --help Show this help
- --token=TOKEN Telegram bot token (or use TELEGRAM_BOT_TOKEN env)
- --model=MODEL LLM model to use [default: anthropic/claude-sonnet-4]
+ -h --help Show this help
+ --token=TOKEN Telegram bot token (or use TELEGRAM_BOT_TOKEN env)
+ --model=MODEL LLM model to use [default: anthropic/claude-sonnet-4]
+ --last=N Number of recent log entries to show [default: 50]
+ <subagent_id> Show logs for a specific subagent (e.g. S-abc123)
|]
move :: Cli.Arguments -> IO ()
move args = do
IO.hSetBuffering IO.stdout IO.LineBuffering
IO.hSetBuffering IO.stderr IO.LineBuffering
- let maybeToken = fmap Text.pack (Cli.getArg args (Cli.longOption "token"))
- Telegram.startBot maybeToken
+ if args `Cli.has` Cli.command "logs"
+ then showLogs args
+ else do
+ let maybeToken = fmap Text.pack (Cli.getArg args (Cli.longOption "token"))
+ Telegram.startBot maybeToken
+
+showLogs :: Cli.Arguments -> IO ()
+showLogs args = do
+ let maybeSubagentId = Cli.getArg args (Cli.argument "subagent_id")
+ let lastN = fromMaybe 50 (readMaybe =<< Cli.getArg args (Cli.longOption "last"))
+
+ case maybeSubagentId of
+ Just sidStr -> do
+ let sid = AuditLog.SubagentId (Text.pack sidStr)
+ let path = AuditLog.subagentLogPath sid
+ exists <- Dir.doesFileExist path
+ if exists
+ then do
+ entries <- AuditLog.readSubagentLogs sid
+ putText <| "=== Subagent " <> Text.pack sidStr <> " (" <> tshow (length entries) <> " entries) ==="
+ traverse_ printLogEntry entries
+ else putText <| "No logs found for subagent: " <> Text.pack sidStr
+ Nothing -> do
+ entries <- AuditLog.getRecentAvaLogs lastN
+ today <- Time.utctDay </ Time.getCurrentTime
+ putText <| "=== Ava logs for " <> Text.pack (Time.formatTime Time.defaultTimeLocale "%Y-%m-%d" today) <> " (last " <> tshow lastN <> ") ==="
+ traverse_ printLogEntry entries
+
+printLogEntry :: AuditLog.AuditLogEntry -> IO ()
+printLogEntry entry = do
+ let ts = Text.pack <| Time.formatTime Time.defaultTimeLocale "%H:%M:%S" (AuditLog.logTimestamp entry)
+ let evType = tshow (AuditLog.logEventType entry)
+ let agent = AuditLog.unAgentId (AuditLog.logAgentId entry)
+ let content = case AuditLog.logContent entry of
+ Aeson.String t -> Text.take 100 t
+ Aeson.Object _ -> "<object>"
+ _ -> "<value>"
+ TextIO.putStrLn <| "[" <> ts <> "] " <> agent <> " | " <> evType <> ": " <> content
test :: Test.Tree
test =