diff options
| author | Ben Sima <ben@bensima.com> | 2025-11-22 16:31:45 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bensima.com> | 2025-11-22 16:31:45 -0500 |
| commit | bb15513a94140c22aa3aea510314f60c94df4d97 (patch) | |
| tree | e9ef6649236eadeb58f6dc445aba302e72edfb9c /Omni/Agent/Worker.hs | |
| parent | 6f4b2c97a24967508f3970b46999052fd1f44e67 (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.hs | 47 |
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 |
