summaryrefslogtreecommitdiff
path: root/Omni/Agent/Worker.hs
diff options
context:
space:
mode:
authorBen Sima <ben@bensima.com>2025-11-22 16:31:45 -0500
committerBen Sima <ben@bensima.com>2025-11-22 16:31:45 -0500
commitbb15513a94140c22aa3aea510314f60c94df4d97 (patch)
treee9ef6649236eadeb58f6dc445aba302e72edfb9c /Omni/Agent/Worker.hs
parent6f4b2c97a24967508f3970b46999052fd1f44e67 (diff)
feat: implement t-1o2bxd11zv9
The task to fix missing Time, Thread, and Credits in the Agent Log has been completed. **Changes Implemented:** 1. **`Omni/Agent/Log.hs`**: * Added `Data.Aeson` and `Data.ByteString` imports for JSON parsing. * Updated `Status` data type to include `statusThread`. * Implemented `LogEntry` data type and `FromJSON` instance to match the `amp` log format. * Added `processLogLine` function to parse JSON log lines and update the global status. * Updated `render` function to display the Thread ID. * Added logic to extract and format `Time` and `Credits` from log entries. 2. **`Omni/Agent/Worker.hs`**: * Added a log monitoring thread using `forkIO` in `runAmp`. * Implemented `monitorLog` to tail the `_/llm/amp.log` file and pass lines to `AgentLog.processLogLine`. * Added `waitForFile` to ensure the log monitor waits for the log file to be created. **Verification:** * Verified that both `Omni/Agent/Log.hs` and `Omni/Agent/Worker.hs` compile successfully using `bild` (ignoring the expected "no main" error for library modules). * Ran `lint` on both files with no errors. The agent status bar should now correctly display the Thread ID, elapsed/current Time, and Credits usage as parsed from the `amp` logs.
Diffstat (limited to 'Omni/Agent/Worker.hs')
-rw-r--r--Omni/Agent/Worker.hs47
1 files changed, 46 insertions, 1 deletions
diff --git a/Omni/Agent/Worker.hs b/Omni/Agent/Worker.hs
index 01099a0..eef59d7 100644
--- a/Omni/Agent/Worker.hs
+++ b/Omni/Agent/Worker.hs
@@ -5,7 +5,9 @@
module Omni.Agent.Worker where
import Alpha
+import Control.Concurrent (forkIO, killThread)
import qualified Data.Text as Text
+import qualified Data.Text.IO as TIO
import qualified Omni.Agent.Core as Core
import qualified Omni.Agent.Git as Git
import qualified Omni.Agent.Log as AgentLog
@@ -13,6 +15,7 @@ import qualified Omni.Task.Core as TaskCore
import qualified System.Directory as Directory
import qualified System.Exit as Exit
import System.FilePath ((</>))
+import qualified System.IO as IO
import qualified System.Process as Process
start :: Core.Worker -> IO ()
@@ -143,6 +146,12 @@ runAmp repo task = do
<> fromMaybe "root" (TaskCore.taskNamespace task)
<> "'.\n"
+ let logFile = repo </> "_/llm/amp.log"
+
+ -- Remove old log file
+ exists <- Directory.doesFileExist logFile
+ when exists (Directory.removeFile logFile)
+
Directory.createDirectoryIfMissing True (repo </> "_/llm")
-- Assume amp is in PATH
@@ -150,7 +159,12 @@ runAmp repo task = do
let cp = (Process.proc "amp" args) {Process.cwd = Just repo}
(_, _, _, ph) <- Process.createProcess cp
- Process.waitForProcess ph
+
+ tid <- forkIO $ monitorLog logFile ph
+
+ exitCode <- Process.waitForProcess ph
+ killThread tid
+ pure exitCode
formatTask :: TaskCore.Task -> Text
formatTask t =
@@ -182,6 +196,37 @@ formatTask t =
where
formatDep dep = " - " <> TaskCore.depId dep <> " [" <> Text.pack (show (TaskCore.depType dep)) <> "]"
+monitorLog :: FilePath -> Process.ProcessHandle -> IO ()
+monitorLog path ph = do
+ waitForFile path
+ IO.withFile path IO.ReadMode $ \h -> do
+ IO.hSetBuffering h IO.LineBuffering
+ loop h
+ where
+ loop h = do
+ eof <- IO.hIsEOF h
+ if eof
+ then do
+ mExit <- Process.getProcessExitCode ph
+ case mExit of
+ Nothing -> do
+ threadDelay 100000 -- 0.1s
+ loop h
+ Just _ -> pure ()
+ else do
+ line <- TIO.hGetLine h
+ AgentLog.processLogLine line
+ loop h
+
+waitForFile :: FilePath -> IO ()
+waitForFile path = do
+ exists <- Directory.doesFileExist path
+ if exists
+ then pure ()
+ else do
+ threadDelay 100000
+ waitForFile path
+
findBaseBranch :: FilePath -> TaskCore.Task -> IO Text
findBaseBranch repo task = do
let deps = TaskCore.taskDependencies task