Let the coordinator and workspace admins hand over tasks and routines

delegate_task takes a task_id to hand over a task already on a list: it
moves to the worker (a workspace's task stays on its list), goes to
doing, and the job is linked back so its end is noted on the task.
hand_over_schedule moves a bot's own routine to another bot, keeping its
workspace. Users get Hand over in the Tasks UI and both routine lists.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-25 11:23:26 +01:00
co-authored by Claude Opus 5.5
parent b4283b607e
commit 93896646c7
36 changed files with 1334 additions and 94 deletions
@@ -3,6 +3,7 @@ import type { BUN_SQLITE_COBBLE_BOTS_QUEUE } from "@/db/types/db";
import insertBotMessage from "../bots/insert-bot-message";
import setBotFace from "../bots/set-bot-face";
import relayJobToRequester from "./relay-job-to-requester";
import noteTrackerTask from "./note-tracker-task";
import jobSessionId from "./job-session-id";
import grabJobUserId from "./grab-job-user-id";
import { BotNeedsYouStatusLine } from "@/src/dict/bot-queue-dict";
@@ -16,7 +17,8 @@ type Params = {
* Wraps up a job that is out of attempts: stamps `finished_at` (so it's
* reported once), tells the user in the bot's conversation and sets the
* bot to needs-you for that user. Its task stays active, since the work isn't done. A
* handed-over job's failure also goes to the bot that handed it over.
* handed-over job's failure also goes to the bot that handed it over, and
* blocks the handed-over task it worked on (`noteTrackerTask`).
*/
export default async function notifyBotJobFailed({
job,
@@ -59,6 +61,8 @@ export default async function notifyBotJobFailed({
})
: null;
await noteTrackerTask({ job, failure: failure_message || job.last_error || "" });
const relay = await relayJobToRequester({
job,
text: failure_message || job.last_error || "",