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:
@@ -4,15 +4,16 @@ import { logError } from "@/src/functions/backend/logger";
|
||||
import grabConnectedUserIds from "@/src/websocket/(functions)/grab-connected-user-ids";
|
||||
import relayChangedBots from "./relay-changed-bots";
|
||||
import relayCreatedBots from "./relay-created-bots";
|
||||
import relayCreatedWorkspaces from "./relay-created-workspaces";
|
||||
import relayNewBotMessages from "./relay-new-bot-messages";
|
||||
import relayNewJobUpdates from "./relay-new-job-updates";
|
||||
import type { LiveRelayCursor } from "./types";
|
||||
|
||||
/**
|
||||
* Keeps this process's sockets current with work done anywhere: every
|
||||
* `AppData.LiveRelayPollMs` it reads new bot messages, new job steps and
|
||||
* changed bots from the database and pushes them to the sockets here
|
||||
* of the users they're for. The process that did the work pushes at once
|
||||
* `AppData.LiveRelayPollMs` it reads new bot messages, new job steps,
|
||||
* new workspaces and changed bots from the database and pushes them to
|
||||
* the sockets here of the users they're for. The process that did the work pushes at once
|
||||
* (`pushBotNotice`); this catches the rest, e.g. a job run by another
|
||||
* server on the same database. Clients ignore what they already have.
|
||||
* Runs in every server process, ungated.
|
||||
@@ -54,6 +55,7 @@ export default async function liveRelay() {
|
||||
const bots_since = cursor.bots_at - AppData.LiveRelayPollMs;
|
||||
|
||||
await relayCreatedBots({ since: bots_since, users });
|
||||
await relayCreatedWorkspaces({ since: bots_since, users });
|
||||
await relayChangedBots({ since: bots_since, users });
|
||||
cursor.bots_at = now;
|
||||
} catch (error) {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||
import type { WorkspaceWithActivity } from "@/src/types";
|
||||
import pushWorkspaceCreated from "@/src/bots-queue/push-workspace-created";
|
||||
|
||||
type Params = {
|
||||
/**
|
||||
* Unix ms: workspaces created since then are pushed.
|
||||
*/
|
||||
since: number;
|
||||
users: Set<string>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Pushes `server:workspace-created` for every workspace created since
|
||||
* `since` to the connected users who see it (`pushWorkspaceCreated`), so a
|
||||
* workspace another process created still shows in the rail. Pushes are
|
||||
* idempotent, so overlapping windows only repeat them.
|
||||
*/
|
||||
export default async function relayCreatedWorkspaces({ since, users }: Params) {
|
||||
if (!users.size) return;
|
||||
|
||||
const workspaces =
|
||||
(
|
||||
await BunSQLite.sql<WorkspaceWithActivity>({
|
||||
sql: `SELECT w.*, 0 AS unread, NULL AS last_activity_at
|
||||
FROM workspaces w
|
||||
WHERE w.created_at > ? AND w.archived = 0`,
|
||||
values: [since],
|
||||
})
|
||||
).payload || [];
|
||||
|
||||
for (const workspace of workspaces) {
|
||||
await pushWorkspaceCreated({ workspace, users });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user