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]>
This commit is contained in:
@@ -7,15 +7,27 @@ import searchComputersTool from "../computer/search-computers-tool";
|
||||
import assignComputerTool from "./assign-computer-tool";
|
||||
import delegateTaskTool from "./delegate-task-tool";
|
||||
import grabBotTools from "./grab-bot-tools";
|
||||
import updateWorkspaceTool from "./update-workspace-tool";
|
||||
import grabUserWorkspaces from "@/src/functions/backend/db/workspaces/grab-user-workspaces";
|
||||
import setWorkspaceInstructionsTool from "./set-workspace-instructions-tool";
|
||||
import startTaskTool from "./start-task-tool";
|
||||
|
||||
type Params = {
|
||||
bot: BUN_SQLITE_COBBLE_BOTS;
|
||||
user_id: number | string;
|
||||
/**
|
||||
* The bot's computers, the current one first (`grabBotComputers`).
|
||||
* The bot's computers where it runs, the current one first
|
||||
* (`grabBotComputers`).
|
||||
*/
|
||||
computers: BUN_SQLITE_COBBLE_COMPUTERS[];
|
||||
/**
|
||||
* The session being answered; tasks report back to it.
|
||||
*/
|
||||
session_id: number | string;
|
||||
/**
|
||||
* The session's workspace, if any.
|
||||
*/
|
||||
workspace_id?: number | string | null;
|
||||
/**
|
||||
* The user message being answered.
|
||||
*/
|
||||
@@ -27,32 +39,37 @@ type Params = {
|
||||
};
|
||||
|
||||
/**
|
||||
* The tools a bot replies in chat with: its own (memory, instructions),
|
||||
* start_task for longer work, search_computers to find what's on its
|
||||
* computers, ask_user_to_take_over when only the user can do something on
|
||||
* one, and for the coordinator delegate_task and assign_computer
|
||||
* (which computers each crew member can use). Anything
|
||||
* else on a computer goes through a task, never mid-reply.
|
||||
* The tools a bot replies in chat with: its own (memory, instructions, and
|
||||
* in a workspace switching its default computer), start_task for longer
|
||||
* work, search_computers to find what's on its computers,
|
||||
* ask_user_to_take_over when only the user can do something on one, and
|
||||
* for the coordinator delegate_task (to the workspace's crew in a
|
||||
* workspace) plus, in its own chat, assign_computer (which computers each
|
||||
* crew member can use) or, in a workspace, set_bot_workspace_instructions.
|
||||
* Anything else on a computer goes through a task, never mid-reply.
|
||||
*/
|
||||
export default async function grabBotChatTools({
|
||||
bot,
|
||||
user_id,
|
||||
computers,
|
||||
session_id,
|
||||
workspace_id,
|
||||
message_id,
|
||||
onTakeOver,
|
||||
}: Params): Promise<HarnessTool[]> {
|
||||
const bot_id = bot.id || 0;
|
||||
const tools = [
|
||||
...grabBotTools({ user_id, bot_id }),
|
||||
...grabBotTools({ user_id, bot_id, workspace_id, computers }),
|
||||
startTaskTool({
|
||||
user_id,
|
||||
bot_id,
|
||||
session_id,
|
||||
computers,
|
||||
message_id,
|
||||
}),
|
||||
...(computers.length
|
||||
? [
|
||||
searchComputersTool({ bot_id, computers }),
|
||||
searchComputersTool({ computers, workspace_id }),
|
||||
askToTakeOverTool({ computers, onAsk: (params) => onTakeOver?.(params) }),
|
||||
]
|
||||
: []),
|
||||
@@ -60,36 +77,52 @@ export default async function grabBotChatTools({
|
||||
|
||||
if (bot.kind != "coordinator") return tools;
|
||||
|
||||
const workspaces = (await grabUserWorkspaces({ user_id })).filter((w) => !w.archived);
|
||||
|
||||
if (workspaces.length) {
|
||||
tools.push(updateWorkspaceTool({ user_id, workspaces, workspace_id }));
|
||||
}
|
||||
|
||||
const workers =
|
||||
(
|
||||
await BunSQLite.sql<BUN_SQLITE_COBBLE_BOTS>({
|
||||
sql: `SELECT * FROM bots WHERE user_id = ? AND kind = 'worker' ORDER BY id ASC`,
|
||||
values: [user_id],
|
||||
sql: workspace_id
|
||||
? `SELECT b.* FROM bots b JOIN workspace_bots wb ON wb.bot_id = b.id AND wb.workspace_id = ?
|
||||
WHERE b.user_id = ? AND b.kind = 'worker' ORDER BY b.id ASC`
|
||||
: `SELECT * FROM bots WHERE user_id = ? AND kind = 'worker' ORDER BY id ASC`,
|
||||
values: workspace_id ? [workspace_id, user_id] : [user_id],
|
||||
})
|
||||
).payload || [];
|
||||
|
||||
if (workers.length) {
|
||||
tools.push(
|
||||
delegateTaskTool({
|
||||
user_id,
|
||||
coordinator_id: bot_id,
|
||||
coordinator_name: bot.name || "The coordinator",
|
||||
workers,
|
||||
}),
|
||||
if (!workers.length) return tools;
|
||||
|
||||
tools.push(
|
||||
delegateTaskTool({
|
||||
user_id,
|
||||
coordinator_id: bot_id,
|
||||
session_id,
|
||||
workspace_id,
|
||||
coordinator_name: bot.name || "The coordinator",
|
||||
workers,
|
||||
}),
|
||||
);
|
||||
|
||||
if (workspace_id) {
|
||||
tools.push(setWorkspaceInstructionsTool({ user_id, workspace_id, workers }));
|
||||
return tools;
|
||||
}
|
||||
|
||||
if (computers.length) {
|
||||
const access = Object.fromEntries(
|
||||
await Promise.all(
|
||||
workers.map(async (worker) => [
|
||||
worker.id || 0,
|
||||
await grabBotComputers({ bot_id: worker.id || 0, user_id }),
|
||||
]),
|
||||
),
|
||||
);
|
||||
|
||||
if (computers.length) {
|
||||
const access = Object.fromEntries(
|
||||
await Promise.all(
|
||||
workers.map(async (worker) => [
|
||||
worker.id || 0,
|
||||
await grabBotComputers({ bot_id: worker.id || 0, user_id }),
|
||||
]),
|
||||
),
|
||||
);
|
||||
|
||||
tools.push(assignComputerTool({ user_id, workers, computers, access }));
|
||||
}
|
||||
tools.push(assignComputerTool({ user_id, workers, computers, access }));
|
||||
}
|
||||
|
||||
return tools;
|
||||
|
||||
Reference in New Issue
Block a user