summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.tasks/tasks.jsonl.lock0
-rw-r--r--Omni/Agent/Log.hs65
-rw-r--r--Omni/Agent/LogTest.hs72
3 files changed, 137 insertions, 0 deletions
diff --git a/.tasks/tasks.jsonl.lock b/.tasks/tasks.jsonl.lock
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.tasks/tasks.jsonl.lock
diff --git a/Omni/Agent/Log.hs b/Omni/Agent/Log.hs
new file mode 100644
index 0000000..33b9722
--- /dev/null
+++ b/Omni/Agent/Log.hs
@@ -0,0 +1,65 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+module Omni.Agent.Log
+ ( LogEntry (..),
+ parseLine,
+ format,
+ )
+where
+
+import Alpha
+import Data.Aeson (FromJSON (..), (.:), (.:?))
+import qualified Data.Aeson as Aeson
+import qualified Data.ByteString.Lazy as BSL
+
+data LogEntry = LogEntry
+ { leMessage :: Text,
+ leLevel :: Maybe Text,
+ leToolName :: Maybe Text,
+ leBatches :: Maybe [[Text]],
+ leMethod :: Maybe Text,
+ lePath :: Maybe Text
+ }
+ deriving (Show, Eq, Generic)
+
+instance FromJSON LogEntry where
+ parseJSON = Aeson.withObject "LogEntry" <| \v ->
+ LogEntry
+ <$> v .: "message"
+ <*> v .:? "level"
+ <*> v .:? "toolName"
+ <*> v .:? "batches"
+ <*> v .:? "method"
+ <*> v .:? "path"
+
+parseLine :: Text -> Maybe LogEntry
+parseLine line = Aeson.decode <| BSL.fromStrict <| encodeUtf8 line
+
+format :: LogEntry -> Maybe Text
+format e =
+ case leMessage e of
+ "executing 1 tools in 1 batch(es)" ->
+ let tool = case leBatches e of
+ Just ((t : _) : _) -> t
+ _ -> "unknown"
+ in Just <| "🤖 THOUGHT: Planning tool execution (" <> tool <> ")"
+ "Tool Bash permitted - action: allow" ->
+ Just "🔧 TOOL: Bash command executed"
+ msg
+ | "Processing tool completion for ledger" == msg && isJust (leToolName e) ->
+ Just <| "✅ TOOL: " <> fromMaybe "" (leToolName e) <> " completed"
+ "ide-fs" ->
+ case leMethod e of
+ Just "readFile" -> Just <| "📂 READ: " <> fromMaybe "" (lePath e)
+ _ -> Nothing
+ "System prompt build complete (no changes)" ->
+ Just "🧠 THINKING..."
+ "System prompt build complete (first build)" ->
+ Just "🚀 STARTING new task context"
+ msg ->
+ case leLevel e of
+ Just "error" -> Just <| "❌ ERROR: " <> msg
+ _ -> Nothing
diff --git a/Omni/Agent/LogTest.hs b/Omni/Agent/LogTest.hs
new file mode 100644
index 0000000..0d085b1
--- /dev/null
+++ b/Omni/Agent/LogTest.hs
@@ -0,0 +1,72 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+-- : out agent-log-test
+module Omni.Agent.LogTest where
+
+import Alpha
+import Omni.Agent.Log
+import qualified Omni.Test as Test
+
+main :: IO ()
+main = Test.run tests
+
+tests :: Test.Tree
+tests =
+ Test.group
+ "Omni.Agent.Log"
+ [ Test.unit "Parse LogEntry" testParse,
+ Test.unit "Format LogEntry" testFormat
+ ]
+
+testParse :: IO ()
+testParse = do
+ let json = "{\"message\": \"executing 1 tools in 1 batch(es)\", \"batches\": [[\"grep\"]]}"
+ let expected =
+ LogEntry
+ { leMessage = "executing 1 tools in 1 batch(es)",
+ leLevel = Nothing,
+ leToolName = Nothing,
+ leBatches = Just [["grep"]],
+ leMethod = Nothing,
+ lePath = Nothing
+ }
+ parseLine json @?= Just expected
+
+testFormat :: IO ()
+testFormat = do
+ let entry =
+ LogEntry
+ { leMessage = "executing 1 tools in 1 batch(es)",
+ leLevel = Nothing,
+ leToolName = Nothing,
+ leBatches = Just [["grep"]],
+ leMethod = Nothing,
+ lePath = Nothing
+ }
+ format entry @?= Just "🤖 THOUGHT: Planning tool execution (grep)"
+
+ let entry2 =
+ LogEntry
+ { leMessage = "some random log",
+ leLevel = Nothing,
+ leToolName = Nothing,
+ leBatches = Nothing,
+ leMethod = Nothing,
+ lePath = Nothing
+ }
+ format entry2 @?= Nothing
+
+ let entry3 =
+ LogEntry
+ { leMessage = "some error",
+ leLevel = Just "error",
+ leToolName = Nothing,
+ leBatches = Nothing,
+ leMethod = Nothing,
+ lePath = Nothing
+ }
+ format entry3 @?= Just "❌ ERROR: some error"
+
+(@?=) :: (Eq a, Show a) => a -> a -> IO ()
+(@?=) = (Test.@?=)