Files
cobble/src/harness/tools/bot/assign-computer-tool.ts
T
tbenandClaude Opus 5.5 0ce61cdb49 Add workspaces, conversation sessions, app-managed computers and pictures
- Rail: Add icon with stacked form modals (bot, workspace, computer),
  coordinator, recent bots with "See all bots", Workspaces section, and
  a workspace mode listing only its crew
- Workspaces: page for context, bots (per-workspace instructions and
  memory), computers (default, link, unlink), models and delete;
  conversations scoped per bot per workspace
- Sessions: conversations split into searchable, reopenable sessions
  with carry-over summaries; sessions and new-session header icons
- Computers: created and provisioned over the docker socket, home dir
  kept at DATA_DIR/computers/<id> after delete; super admins only
- Models: workspace settings win over a bot's own, then the defaults
- Pictures for bots and workspaces; bots editable from the header
- Coordinator tools: update_workspace, set_bot_workspace_instructions

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 08:39:33 +01:00

83 lines
2.9 KiB
TypeScript

import { z } from "zod";
import type { BUN_SQLITE_COBBLE_BOTS, BUN_SQLITE_COBBLE_COMPUTERS } from "@/db/types/db";
import addBotToComputer from "@/src/functions/backend/db/computers/add-bot-to-computer";
import removeBotFromComputer from "@/src/functions/backend/db/computers/remove-bot-from-computer";
import computerRef from "@/src/utils/computer-ref";
import type { HarnessTool } from "../../types";
type Params = {
user_id: number | string;
/**
* The user's worker bots.
*/
workers: BUN_SQLITE_COBBLE_BOTS[];
/**
* Every computer the user has (the coordinator's).
*/
computers: BUN_SQLITE_COBBLE_COMPUTERS[];
/**
* Each worker's computers now, by bot id, for the description.
*/
access: Record<number, BUN_SQLITE_COBBLE_COMPUTERS[]>;
};
type Args = {
bot_id: number;
computer_id: number;
access: "grant" | "revoke";
};
/**
* Lets the coordinator give a crew member access to one of the user's
* computers in its own chat (`bot_computers`), or take it away. In a
* workspace, bots use the workspace's computers instead.
*/
export default function assignComputerTool({
user_id,
workers,
computers,
access,
}: Params): HarnessTool<Args> {
const crew = workers
.map((bot) => {
const has = access[bot.id || 0] || [];
return `${bot.id}: ${bot.name} (${has.length ? has.map((c) => computerRef({ id: c.id || 0 })).join(", ") : "no computer"})`;
})
.join("; ");
return {
name: "assign_computer",
description: `Give a crew member access to a computer, or take it away. A bot works on its computers and its delegated tasks run on the one it's on. Crew and their computers now: ${crew}. Computers: ${computers
.map((c) => `${computerRef({ id: c.id || 0 })} ${c.name || "Computer"}`)
.join(", ")}.`,
schema: z.object({
bot_id: z.number().int(),
computer_id: z.number().int(),
access: z.enum(["grant", "revoke"]),
}),
run: async ({ args }) => {
const worker = workers.find((bot) => bot.id == args.bot_id);
const computer = computers.find((c) => c.id == args.computer_id);
if (!worker?.id) {
throw new Error(`No crew member has id ${args.bot_id}.`);
}
if (!computer?.id) {
throw new Error(`No computer has id ${args.computer_id}.`);
}
const ref = computerRef({ id: computer.id });
if (args.access == "grant") {
await addBotToComputer({ user_id, bot_id: worker.id, computer_id: computer.id });
return `${worker.name} can use ${ref} now.`;
}
await removeBotFromComputer({ user_id, bot_id: worker.id, computer_id: computer.id });
return `${worker.name} can't use ${ref} in its own chat any more. In a workspace it still uses the workspace's computers.`;
},
};
}