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:
@@ -0,0 +1,63 @@
|
||||
import { z } from "zod";
|
||||
import type { BUN_SQLITE_COBBLE_WORKSPACES } from "@/db/types/db";
|
||||
import { AppData } from "@/src/data/app-data";
|
||||
import updateWorkspace from "@/src/functions/backend/db/workspaces/update-workspace";
|
||||
import type { HarnessTool } from "../../types";
|
||||
|
||||
type Params = {
|
||||
user_id: number | string;
|
||||
/**
|
||||
* The user's workspaces the coordinator may change.
|
||||
*/
|
||||
workspaces: BUN_SQLITE_COBBLE_WORKSPACES[];
|
||||
/**
|
||||
* The workspace the conversation is in: the one changed when no id is
|
||||
* given.
|
||||
*/
|
||||
workspace_id?: number | string | null;
|
||||
};
|
||||
|
||||
type Args = {
|
||||
workspace_id?: number;
|
||||
name?: string;
|
||||
description?: string;
|
||||
context?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Lets the coordinator change a workspace's record: its name, its
|
||||
* one-line description and the context every bot working there gets.
|
||||
*/
|
||||
export default function updateWorkspaceTool({ user_id, workspaces, workspace_id }: Params): HarnessTool<Args> {
|
||||
const list = workspaces.map((w) => `${w.id}: ${w.name}`).join("; ");
|
||||
|
||||
return {
|
||||
name: "update_workspace",
|
||||
description: `Change a workspace: its name, its one-line description, or its context (markdown every bot working there gets in its prompt). Only the fields you give change; \`context\` replaces the whole text, so keep what still applies. Use it when the user asks, or to record something every bot in that workspace must know.${workspace_id ? " Leave out workspace_id for this workspace." : ""} Workspaces: ${list}.`,
|
||||
schema: z.object({
|
||||
workspace_id: z.number().int().optional(),
|
||||
name: z.string().trim().min(1).max(60).optional(),
|
||||
description: z.string().trim().max(240).optional(),
|
||||
context: z.string().trim().max(AppData.PromptMaxLength).optional(),
|
||||
}),
|
||||
run: async ({ args }) => {
|
||||
const target = workspaces.find((w) => w.id == (args.workspace_id || workspace_id));
|
||||
|
||||
if (!target?.id) {
|
||||
throw new Error(`No workspace has id ${args.workspace_id ?? "(none given)"}. Workspaces: ${list}.`);
|
||||
}
|
||||
|
||||
if (args.name === undefined && args.description === undefined && args.context === undefined) {
|
||||
throw new Error(`Give a name, a description or a context to change.`);
|
||||
}
|
||||
|
||||
await updateWorkspace({
|
||||
user_id,
|
||||
workspace_id: target.id,
|
||||
data: { name: args.name, description: args.description, system_prompt: args.context },
|
||||
});
|
||||
|
||||
return `${args.name || target.name} is saved. Bots there get the change from their next run.`;
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user