summaryrefslogtreecommitdiff
path: root/Omni/Agent/Worker.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Omni/Agent/Worker.hs')
-rw-r--r--Omni/Agent/Worker.hs64
1 files changed, 43 insertions, 21 deletions
diff --git a/Omni/Agent/Worker.hs b/Omni/Agent/Worker.hs
index 3bf4579..c01a853 100644
--- a/Omni/Agent/Worker.hs
+++ b/Omni/Agent/Worker.hs
@@ -5,7 +5,15 @@
module Omni.Agent.Worker where
import Alpha
+import Control.Concurrent (forkIO, killThread, threadDelay)
+import Control.Monad (forever)
+import qualified Data.Aeson as Aeson
+import qualified Data.Aeson.KeyMap as KM
+import qualified Data.ByteString.Lazy as BL
+import qualified Data.Scientific as Scientific
import qualified Data.Text as Text
+import qualified Data.Text.IO as TIO
+import qualified Data.Time as Time
import qualified Omni.Agent.Core as Core
import qualified Omni.Agent.Git as Git
import qualified Omni.Agent.Log as AgentLog
@@ -15,9 +23,6 @@ import qualified System.Exit as Exit
import System.FilePath ((</>))
import qualified System.IO as IO
import qualified System.Process as Process
-import Control.Concurrent (forkIO, killThread, threadDelay)
-import qualified Data.Text.IO as TIO
-import Control.Monad (forever)
start :: Core.Worker -> IO ()
start worker = do
@@ -62,7 +67,7 @@ processTask worker task = do
AgentLog.updateActivity ("Claiming task " <> tid)
-- Claim task
- TaskCore.updateTaskStatus tid TaskCore.InProgress
+ TaskCore.updateTaskStatus tid TaskCore.InProgress []
-- Commit claim locally
Git.commit repo ("task: claim " <> tid)
@@ -91,18 +96,20 @@ processTask worker task = do
-- Run Amp
AgentLog.updateActivity "Running Amp agent..."
- exitCode <- runAmp repo task
+ (exitCode, output) <- runAmp repo task
case exitCode of
Exit.ExitSuccess -> do
AgentLog.log "Agent finished successfully"
-- Update status to Review (bundled with feature commit)
- TaskCore.updateTaskStatus tid TaskCore.Review
+ TaskCore.updateTaskStatus tid TaskCore.Review []
-- Commit changes
- -- We should check if there are changes, but 'git add .' is safe.
- Git.commit repo ("feat: implement " <> tid)
+ -- We use the agent's output as the extended commit description
+ let summary = Text.strip output
+ let commitMsg = "feat: implement " <> tid <> "\n\n" <> summary
+ Git.commit repo commitMsg
-- Submit for review
AgentLog.updateActivity "Submitting for review..."
@@ -115,18 +122,17 @@ processTask worker task = do
Git.syncWithLive repo
-- Update status to Review (for signaling)
- TaskCore.updateTaskStatus tid TaskCore.Review
+ TaskCore.updateTaskStatus tid TaskCore.Review []
Git.commit repo ("task: review " <> tid)
-
+
AgentLog.log ("[✓] Task " <> tid <> " completed")
AgentLog.update (\s -> s {AgentLog.statusTask = Nothing})
-
Exit.ExitFailure code -> do
AgentLog.log ("Agent failed with code " <> tshow code)
AgentLog.updateActivity "Agent failed, retrying..."
threadDelay (10 * 1000000) -- Sleep 10s
-runAmp :: FilePath -> TaskCore.Task -> IO Exit.ExitCode
+runAmp :: FilePath -> TaskCore.Task -> IO (Exit.ExitCode, Text)
runAmp repo task = do
let prompt =
"You are a Worker Agent.\n"
@@ -138,7 +144,8 @@ runAmp repo task = do
<> "3. Run tests to verify your work (e.g., 'bild --test Omni/Namespace').\n"
<> "4. Fix any errors found during testing.\n"
<> "5. Do NOT update the task status or manage git branches (the system handles that).\n"
- <> "6. When finished and tested, exit.\n\n"
+ <> "6. Do NOT run 'git commit'. The system will commit your changes automatically.\n"
+ <> "7. When finished and tested, exit.\n\n"
<> "Context:\n"
<> "- You are working in '"
<> Text.pack repo
@@ -149,21 +156,36 @@ runAmp repo task = do
Directory.createDirectoryIfMissing True (repo </> "_/llm")
let logPath = repo </> "_/llm/amp.log"
+
-- Ensure log file is empty/exists
IO.writeFile logPath ""
+ -- Read AGENTS.md
+ agentsMd <-
+ fmap (fromMaybe "") <| do
+ exists <- Directory.doesFileExist (repo </> "AGENTS.md")
+ if exists
+ then Just </ readFile (repo </> "AGENTS.md")
+ else pure Nothing
+
+ let fullPrompt =
+ prompt
+ <> "\n\nREPOSITORY GUIDELINES (AGENTS.md):\n"
+ <> agentsMd
+
-- Monitor log file
- monitorThread <- forkIO (monitorLog logPath)
+ tidLog <- forkIO (monitorLog logPath)
-- Assume amp is in PATH
- let args = ["--log-level", "debug", "--log-file", "_/llm/amp.log", "--dangerously-allow-all", "-x", Text.unpack prompt]
+ let args = ["--log-level", "debug", "--log-file", "_/llm/amp.log", "--dangerously-allow-all", "-x", Text.unpack fullPrompt]
let cp = (Process.proc "amp" args) {Process.cwd = Just repo}
- (_, _, _, ph) <- Process.createProcess cp
- exitCode <- Process.waitForProcess ph
+ (exitCode, out, _err) <- Process.readCreateProcessWithExitCode cp ""
+
+ -- Cleanup
+ killThread tidLog
- killThread monitorThread
- pure exitCode
+ pure (exitCode, Text.pack out)
formatTask :: TaskCore.Task -> Text
formatTask t =
@@ -221,9 +243,9 @@ monitorLog path = do
-- Wait for file to exist
waitForFile path
- IO.withFile path IO.ReadMode $ \h -> do
+ IO.withFile path IO.ReadMode <| \h -> do
IO.hSetBuffering h IO.LineBuffering
- forever $ do
+ forever <| do
eof <- IO.hIsEOF h
if eof
then threadDelay 100000 -- 0.1s