Let the coordinator create workspaces and write findings in tasks

create_workspace gives the coordinator a way to start a workspace with its shared context, and the tool list is shared, so a new id can be used by create_bot or add_bot_to_workspace in the same reply.

A coordinator's tasks now get create_workspace and update_workspace too: the research task that had the material could only report it, never write it into the workspace, so the coordinator promised an update it had no turn to make.

A workspace created from chat is pushed as server:workspace-created, from the tool and from the live relay, so the rail shows it without a reload.
This commit is contained in:
2026-10-19 14:32:47 +01:00
parent 1cafb40eef
commit 550aaeabac
12 changed files with 268 additions and 16 deletions
@@ -1,7 +1,7 @@
import { useState } from "react";
import type { BUN_SQLITE_COBBLE_BOT_MESSAGES } from "@/db/types/db";
import useServerEvent from "@/src/hooks/use-server-event";
import type { WorkspaceWithActivity } from "@/src/types";
import type { WorkspaceCreatedData, WorkspaceWithActivity } from "@/src/types";
type Params = {
workspaces: WorkspaceWithActivity[];
@@ -12,11 +12,29 @@ type Params = {
};
/**
* The user's workspaces, marked unread as bot messages arrive in them.
* The user's workspaces, marked unread as bot messages arrive in them and
* kept current when one is created (a bot can create one, so it shows
* without a reload).
*/
export default function useLiveWorkspaces({ workspaces, open_workspace_id }: Params) {
const [live, setLive] = useState(workspaces);
useServerEvent({
event: "server:workspace-created",
onData: (data: WorkspaceCreatedData) => {
setLive((prev) => {
if (prev.some((workspace) => workspace.id == data.workspace.id)) return prev;
/** The rail lists them oldest first (`grabUserWorkspaces`). */
const at = prev.findIndex((workspace) => Number(workspace.id) > Number(data.workspace.id));
if (at < 0) return [...prev, data.workspace];
return [...prev.slice(0, at), data.workspace, ...prev.slice(at)];
});
},
});
useServerEvent({
event: "server:bot-message",
onData: (message: BUN_SQLITE_COBBLE_BOT_MESSAGES) => {