summaryrefslogtreecommitdiff
path: root/Omni/Agent/Log.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Omni/Agent/Log.hs')
-rw-r--r--Omni/Agent/Log.hs102
1 files changed, 54 insertions, 48 deletions
diff --git a/Omni/Agent/Log.hs b/Omni/Agent/Log.hs
index 99b40ae..59efb38 100644
--- a/Omni/Agent/Log.hs
+++ b/Omni/Agent/Log.hs
@@ -6,16 +6,16 @@
module Omni.Agent.Log where
import Alpha
+import Data.Aeson (Value (..), decode)
+import qualified Data.Aeson.KeyMap as KM
+import qualified Data.ByteString.Lazy as BL
import Data.IORef (IORef, modifyIORef', newIORef, readIORef, writeIORef)
+import qualified Data.Text.Encoding as TextEnc
import qualified Data.Text.IO as TIO
+import qualified Data.Vector as V
import qualified System.Console.ANSI as ANSI
import qualified System.IO as IO
import System.IO.Unsafe (unsafePerformIO)
-import Data.Aeson (Value(..), decode)
-import qualified Data.Aeson.KeyMap as KM
-import qualified Data.ByteString.Lazy as BL
-import qualified Data.Text.Encoding as TextEnc
-import qualified Data.Vector as V
-- | Parsed log entry
data LogEntry = LogEntry
@@ -32,6 +32,7 @@ data LogEntry = LogEntry
data Status = Status
{ statusWorker :: Text,
statusTask :: Maybe Text,
+ statusThreadId :: Maybe Text,
statusFiles :: Int,
statusCredits :: Double,
statusTime :: Text, -- formatted time string
@@ -44,6 +45,7 @@ emptyStatus workerName =
Status
{ statusWorker = workerName,
statusTask = Nothing,
+ statusThreadId = Nothing,
statusFiles = 0,
statusCredits = 0.0,
statusTime = "00:00",
@@ -60,10 +62,9 @@ init :: Text -> IO ()
init workerName = do
IO.hSetBuffering IO.stderr IO.LineBuffering
writeIORef currentStatus (emptyStatus workerName)
- -- Reserve 2 lines at bottom
- IO.hPutStrLn IO.stderr ""
- IO.hPutStrLn IO.stderr ""
- ANSI.hCursorUp IO.stderr 2
+ -- Reserve 5 lines at bottom
+ replicateM_ 5 (IO.hPutStrLn IO.stderr "")
+ ANSI.hCursorUp IO.stderr 5
-- | Update the status
update :: (Status -> Status) -> IO ()
@@ -79,9 +80,7 @@ updateActivity msg = update (\s -> s {statusActivity = msg})
processLogLine :: Text -> IO ()
processLogLine line = do
let entry = parseLine line
- case entry >>= formatLogEntry of
- Just msg -> updateActivity msg
- Nothing -> pure ()
+ Data.Foldable.for_ (entry +> formatLogEntry) updateActivity
-- | Parse a JSON log line into a LogEntry
parseLine :: Text -> Maybe LogEntry
@@ -109,12 +108,12 @@ parseLine line = do
getBatches o =
case KM.lookup "batches" o of
Just (Array b) ->
- Just <|
- mapMaybe
+ Just
+ <| mapMaybe
( \case
Array b0 ->
- Just <|
- mapMaybe
+ Just
+ <| mapMaybe
( \case
String s -> Just s
_ -> Nothing
@@ -135,37 +134,38 @@ formatLogEntry LogEntry {..} =
((t : _) : _) -> t
_ -> "unknown"
Just ("THOUGHT: Planning tool execution (" <> firstTool <> ")")
-
Just "Tool Bash permitted - action: allow" ->
Just "TOOL: Bash command executed"
-
- Just "Processing tool completion for ledger" | isJust leToolName ->
- Just ("TOOL: " <> fromMaybe "unknown" leToolName <> " completed")
-
+ Just "Processing tool completion for ledger"
+ | isJust leToolName ->
+ Just ("TOOL: " <> fromMaybe "unknown" leToolName <> " completed")
Just "ide-fs" | leMethod == Just "readFile" ->
case lePath of
Just p -> Just ("READ: " <> p)
_ -> Nothing
-
Just "System prompt build complete (no changes)" ->
Just "THINKING..."
-
Just "System prompt build complete (first build)" ->
Just "STARTING new task context"
-
- Just msg | leLevel == Just "error" ->
- Just ("ERROR: " <> msg)
-
+ Just msg
+ | leLevel == Just "error" ->
+ Just ("ERROR: " <> msg)
_ -> Nothing
-- | Log a scrolling message (appears above status bars)
log :: Text -> IO ()
log msg = do
- -- Clear status bars
+ -- Clear status bars (5 lines)
+ ANSI.hClearLine IO.stderr
+ ANSI.hCursorDown IO.stderr 1
ANSI.hClearLine IO.stderr
ANSI.hCursorDown IO.stderr 1
ANSI.hClearLine IO.stderr
- ANSI.hCursorUp IO.stderr 1
+ ANSI.hCursorDown IO.stderr 1
+ ANSI.hClearLine IO.stderr
+ ANSI.hCursorDown IO.stderr 1
+ ANSI.hClearLine IO.stderr
+ ANSI.hCursorUp IO.stderr 4
-- Print message (scrolls screen)
TIO.hPutStrLn IO.stderr msg
@@ -174,37 +174,43 @@ log msg = do
-- (Since we scrolled, we are now on the line above where the first status line should be)
render
--- | Render the two status lines
+-- | Render the 5 status lines (Vertical Layout)
render :: IO ()
render = do
Status {..} <- readIORef currentStatus
- -- Line 1: Meta
- -- [Worker: name] Task: t-123 | Files: 3 | Credits: $0.45 | Time: 05:23
let taskStr = maybe "None" identity statusTask
- meta =
- "[Worker: "
- <> statusWorker
- <> "] Task: "
- <> taskStr
- <> " | Files: "
- <> tshow statusFiles
- <> " | Credits: $"
- <> tshow statusCredits
- <> " | Time: "
- <> statusTime
+ threadStr = maybe "None" identity statusThreadId
+
+ -- Line 1: Worker + Time
+ ANSI.hSetCursorColumn IO.stderr 0
+ ANSI.hClearLine IO.stderr
+ TIO.hPutStr IO.stderr <| "Worker: " <> statusWorker <> " | Time: " <> statusTime
+
+ -- Line 2: Task
+ ANSI.hCursorDown IO.stderr 1
+ ANSI.hSetCursorColumn IO.stderr 0
+ ANSI.hClearLine IO.stderr
+ TIO.hPutStr IO.stderr <| "Task: " <> taskStr
+
+ -- Line 3: Thread
+ ANSI.hCursorDown IO.stderr 1
+ ANSI.hSetCursorColumn IO.stderr 0
+ ANSI.hClearLine IO.stderr
+ TIO.hPutStr IO.stderr <| "Thread: " <> threadStr
+ -- Line 4: Credits
+ ANSI.hCursorDown IO.stderr 1
ANSI.hSetCursorColumn IO.stderr 0
ANSI.hClearLine IO.stderr
- TIO.hPutStr IO.stderr meta
+ TIO.hPutStr IO.stderr <| "Credits: $" <> tshow statusCredits
- -- Line 2: Activity
- -- [14:05:22] > Thinking...
+ -- Line 5: Activity
ANSI.hCursorDown IO.stderr 1
ANSI.hSetCursorColumn IO.stderr 0
ANSI.hClearLine IO.stderr
TIO.hPutStr IO.stderr ("> " <> statusActivity)
- -- Return cursor to line 1
- ANSI.hCursorUp IO.stderr 1
+ -- Return cursor to Line 1
+ ANSI.hCursorUp IO.stderr 4
IO.hFlush IO.stderr