Let the coordinator create bots and put them in workspaces
The coordinator had no tool to add a worker, so a request to create one fell back to update_workspace and wrote a bot that did not exist into the workspace context. create_bot now adds a worker with its name, role and instructions and joins it to a workspace, and add_bot_to_workspace puts an existing worker in one. Both are coordinator-only and chat-replies-only, and createBot still enforces the crew-manager check. The coordinator's prompts now say how a bot gets created, and that one which does not exist is never written into workspace context. pick-free-hue moves to utils so the tool can pick a hue without importing from layouts.
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||
import { z } from "zod";
|
||||
import type { BUN_SQLITE_COBBLE_BOTS, BUN_SQLITE_COBBLE_WORKSPACES } from "@/db/types/db";
|
||||
import addBotToWorkspace from "@/src/functions/backend/db/workspaces/add-bot-to-workspace";
|
||||
import type { HarnessTool } from "../../types";
|
||||
|
||||
type Params = {
|
||||
user_id: number | string;
|
||||
/**
|
||||
* The user's worker bots.
|
||||
*/
|
||||
workers: BUN_SQLITE_COBBLE_BOTS[];
|
||||
/**
|
||||
* The user's live workspaces.
|
||||
*/
|
||||
workspaces: BUN_SQLITE_COBBLE_WORKSPACES[];
|
||||
};
|
||||
|
||||
type Args = {
|
||||
bot_id: number;
|
||||
workspace_id: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Lets the coordinator put a crew member in one of the user's workspaces,
|
||||
* so the user can talk to it there and it gets that workspace's context,
|
||||
* computers and models. Offered in the coordinator's own chat only, where
|
||||
* the whole crew and every live workspace are known.
|
||||
*/
|
||||
export default function addBotToWorkspaceTool({
|
||||
user_id,
|
||||
workers,
|
||||
workspaces,
|
||||
}: Params): HarnessTool<Args> {
|
||||
const crew = workers.map((bot) => `${bot.id}: ${bot.name}`).join("; ");
|
||||
const list = workspaces.map((w) => `${w.id}: ${w.name}`).join("; ");
|
||||
|
||||
return {
|
||||
name: "add_bot_to_workspace",
|
||||
description: `Put a crew member in one of the user's workspaces. There they work with the workspace's context, its computers and its models, and the user chats with them in it. Use it when the user asks for a bot to work in a workspace, or after create_bot made one without a place. Crew: ${crew || "none"}. Workspaces: ${list || "none"}.`,
|
||||
schema: z.object({
|
||||
bot_id: z.number().int(),
|
||||
workspace_id: z.number().int(),
|
||||
}),
|
||||
run: async ({ args }) => {
|
||||
const worker = workers.find((bot) => bot.id == args.bot_id);
|
||||
const workspace = workspaces.find((w) => w.id == args.workspace_id);
|
||||
|
||||
if (!worker?.id) {
|
||||
throw new Error(`No crew member has id ${args.bot_id}. Crew: ${crew || "none"}.`);
|
||||
}
|
||||
|
||||
if (!workspace?.id) {
|
||||
throw new Error(
|
||||
`No workspace has id ${args.workspace_id}. Workspaces: ${list || "none"}.`,
|
||||
);
|
||||
}
|
||||
|
||||
const already =
|
||||
(
|
||||
await BunSQLite.sql<{ present: number }>({
|
||||
sql: `SELECT 1 AS present FROM workspace_bots WHERE workspace_id = ? AND bot_id = ? LIMIT 1`,
|
||||
values: [workspace.id, worker.id],
|
||||
})
|
||||
).payload?.[0] || null;
|
||||
|
||||
if (already) {
|
||||
return `${worker.name} is already in ${workspace.name}.`;
|
||||
}
|
||||
|
||||
await addBotToWorkspace({
|
||||
user_id,
|
||||
workspace_id: workspace.id,
|
||||
bot_id: worker.id,
|
||||
});
|
||||
|
||||
return `${worker.name} joined ${workspace.name}.`;
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user