summaryrefslogtreecommitdiff
path: root/Omni/Task
diff options
context:
space:
mode:
authorBen Sima <ben@bensima.com>2025-11-27 14:14:40 -0500
committerBen Sima <ben@bensima.com>2025-11-27 14:14:40 -0500
commitbe32ee30dacc65406c1e949765786446345f37b2 (patch)
treedcb489bbbaee9aba21cb07ecacef2475be26e2dd /Omni/Task
parentaad0175d6bb2b90d2c78a4a73844ae30ea6cefac (diff)
Add human notes field for intervention tasks
All tests pass. Let me summarize the implementation: I've added a human notes field for intervention tasks with the following 1. **Omni/Task/Core.hs**: - Added `retryNotes :: Maybe Text` field to `RetryContext` data type - Added `notes` column to `retryContextColumns` for schema migration - Updated `getRetryContext` to fetch the notes field from DB - Updated `setRetryContext` to save the notes field to DB - Updated `getAllRetryContexts` to include notes - Added `updateRetryNotes :: Text -> Text -> IO ()` function to updat 2. **Omni/Jr/Web.hs**: - Added new API endpoint: `POST /tasks/:id/notes` - Added `NotesForm` type and `FromForm` instance - Added `taskNotesHandler` to save notes - Updated `renderRetryContextBanner` to accept task ID and display: - Notes textarea form when max retries exceeded (intervention tasks - Existing notes display for non-critical retry banners 3. **Omni/Agent/Worker.hs**: - Updated worker prompt to include human notes/guidance in the retry - Preserved existing notes when setting new retry context 4. **Omni/Jr.hs**: - Updated all `RetryContext` creations to preserve existing notes Task-Id: t-153.5
Diffstat (limited to 'Omni/Task')
-rw-r--r--Omni/Task/Core.hs48
1 files changed, 35 insertions, 13 deletions
diff --git a/Omni/Task/Core.hs b/Omni/Task/Core.hs
index 5af4ce4..4eac9b5 100644
--- a/Omni/Task/Core.hs
+++ b/Omni/Task/Core.hs
@@ -78,7 +78,8 @@ data RetryContext = RetryContext
retryOriginalCommit :: Text,
retryConflictFiles :: [Text],
retryAttempt :: Int,
- retryReason :: Text -- "merge_conflict" | "ci_failure" | "rejected"
+ retryReason :: Text, -- "merge_conflict" | "ci_failure" | "rejected"
+ retryNotes :: Maybe Text -- Human notes/guidance for intervention
}
deriving (Show, Eq, Generic)
@@ -422,7 +423,8 @@ retryContextColumns =
("original_commit", "TEXT"),
("conflict_files", "TEXT"),
("attempt", "INTEGER"),
- ("reason", "TEXT")
+ ("reason", "TEXT"),
+ ("notes", "TEXT")
]
-- | Migrate a table by adding any missing columns
@@ -1047,21 +1049,22 @@ getRetryContext tid =
rows <-
SQL.query
conn
- "SELECT task_id, original_commit, conflict_files, attempt, reason FROM retry_context WHERE task_id = ?"
+ "SELECT task_id, original_commit, conflict_files, attempt, reason, notes FROM retry_context WHERE task_id = ?"
(SQL.Only tid) ::
- IO [(Text, Text, Text, Int, Text)]
+ IO [(Text, Text, Text, Int, Text, Maybe Text)]
case rows of
[] -> pure Nothing
- ((taskId, commit, filesJson, attempt, reason) : _) ->
+ ((taskId', commit, filesJson, attempt, reason, notes) : _) ->
let files = fromMaybe [] (decode (BLC.pack <| T.unpack filesJson))
in pure
<| Just
RetryContext
- { retryTaskId = taskId,
+ { retryTaskId = taskId',
retryOriginalCommit = commit,
retryConflictFiles = files,
retryAttempt = attempt,
- retryReason = reason
+ retryReason = reason,
+ retryNotes = notes
}
-- | Set retry context for a task (upsert)
@@ -1071,8 +1074,8 @@ setRetryContext ctx =
let filesJson = T.pack <| BLC.unpack <| encode (retryConflictFiles ctx)
SQL.execute
conn
- "INSERT OR REPLACE INTO retry_context (task_id, original_commit, conflict_files, attempt, reason) VALUES (?, ?, ?, ?, ?)"
- (retryTaskId ctx, retryOriginalCommit ctx, filesJson, retryAttempt ctx, retryReason ctx)
+ "INSERT OR REPLACE INTO retry_context (task_id, original_commit, conflict_files, attempt, reason, notes) VALUES (?, ?, ?, ?, ?, ?)"
+ (retryTaskId ctx, retryOriginalCommit ctx, filesJson, retryAttempt ctx, retryReason ctx, retryNotes ctx)
-- | Clear retry context for a task (on successful merge)
clearRetryContext :: Text -> IO ()
@@ -1173,15 +1176,34 @@ getAllRetryContexts =
rows <-
SQL.query_
conn
- "SELECT task_id, original_commit, conflict_files, attempt, reason FROM retry_context" ::
- IO [(Text, Text, Text, Int, Text)]
+ "SELECT task_id, original_commit, conflict_files, attempt, reason, notes FROM retry_context" ::
+ IO [(Text, Text, Text, Int, Text, Maybe Text)]
pure
[ RetryContext
{ retryTaskId = tid,
retryOriginalCommit = commit,
retryConflictFiles = fromMaybe [] (decode (BLC.pack (T.unpack filesJson))),
retryAttempt = attempt,
- retryReason = reason
+ retryReason = reason,
+ retryNotes = notes
}
- | (tid, commit, filesJson, attempt, reason) <- rows
+ | (tid, commit, filesJson, attempt, reason, notes) <- rows
]
+
+-- | Update just the notes field for a retry context
+updateRetryNotes :: Text -> Text -> IO ()
+updateRetryNotes tid notes = do
+ maybeCtx <- getRetryContext tid
+ case maybeCtx of
+ Nothing ->
+ setRetryContext
+ RetryContext
+ { retryTaskId = tid,
+ retryOriginalCommit = "",
+ retryConflictFiles = [],
+ retryAttempt = 0,
+ retryReason = "",
+ retryNotes = Just notes
+ }
+ Just ctx ->
+ setRetryContext ctx {retryNotes = Just notes}