import { Type } from '@sinclair/typebox'; import type { ToolDefinition } from '@mariozechner/pi-coding-agent'; import type { Brain } from '@mosaicstack/brain'; export function createBrainTools(brain: Brain): ToolDefinition[] { const listProjects: ToolDefinition = { name: 'brain_list_projects', label: 'List Projects', description: 'List all projects in the brain.', parameters: Type.Object({}), async execute() { const projects = await brain.projects.findAll(); return { content: [{ type: 'text' as const, text: JSON.stringify(projects, null, 2) }], details: undefined, }; }, }; const getProject: ToolDefinition = { name: 'brain_get_project', label: 'Get Project', description: 'Get a project by ID.', parameters: Type.Object({ id: Type.String({ description: 'Project ID (UUID)' }), }), async execute(_toolCallId, params) { const { id } = params as { id: string }; const project = await brain.projects.findById(id); return { content: [ { type: 'text' as const, text: project ? JSON.stringify(project, null, 2) : `Project not found: ${id}`, }, ], details: undefined, }; }, }; const listTasks: ToolDefinition = { name: 'brain_list_tasks', label: 'List Tasks', description: 'List tasks, optionally filtered by project, mission, or status.', parameters: Type.Object({ projectId: Type.Optional(Type.String({ description: 'Filter by project ID' })), missionId: Type.Optional(Type.String({ description: 'Filter by mission ID' })), status: Type.Optional(Type.String({ description: 'Filter by status' })), }), async execute(_toolCallId, params) { const p = params as { projectId?: string; missionId?: string; status?: string }; type TaskStatus = 'not-started' | 'in-progress' | 'blocked' | 'done' | 'cancelled'; let tasks; if (p.projectId) tasks = await brain.tasks.findByProject(p.projectId); else if (p.missionId) tasks = await brain.tasks.findByMission(p.missionId); else if (p.status) tasks = await brain.tasks.findByStatus(p.status as TaskStatus); else tasks = await brain.tasks.findAll(); return { content: [{ type: 'text' as const, text: JSON.stringify(tasks, null, 2) }], details: undefined, }; }, }; const createTask: ToolDefinition = { name: 'brain_create_task', label: 'Create Task', description: 'Create a new task in the brain.', parameters: Type.Object({ title: Type.String({ description: 'Task title' }), description: Type.Optional(Type.String({ description: 'Task description' })), projectId: Type.Optional(Type.String({ description: 'Project ID' })), missionId: Type.Optional(Type.String({ description: 'Mission ID' })), priority: Type.Optional( Type.String({ description: 'Priority: low, medium, high, critical' }), ), }), async execute(_toolCallId, params) { const p = params as { title: string; description?: string; projectId?: string; missionId?: string; priority?: string; }; type Priority = 'low' | 'medium' | 'high' | 'critical'; const task = await brain.tasks.create({ ...p, priority: p.priority as Priority | undefined, }); return { content: [{ type: 'text' as const, text: JSON.stringify(task, null, 2) }], details: undefined, }; }, }; const updateTask: ToolDefinition = { name: 'brain_update_task', label: 'Update Task', description: 'Update an existing task.', parameters: Type.Object({ id: Type.String({ description: 'Task ID' }), title: Type.Optional(Type.String()), description: Type.Optional(Type.String()), status: Type.Optional( Type.String({ description: 'not-started, in-progress, blocked, done, cancelled' }), ), priority: Type.Optional(Type.String()), }), async execute(_toolCallId, params) { const { id, ...updates } = params as { id: string; title?: string; description?: string; status?: string; priority?: string; }; type TaskStatus = 'not-started' | 'in-progress' | 'blocked' | 'done' | 'cancelled'; type Priority = 'low' | 'medium' | 'high' | 'critical'; const task = await brain.tasks.update(id, { ...updates, status: updates.status as TaskStatus | undefined, priority: updates.priority as Priority | undefined, }); return { content: [ { type: 'text' as const, text: task ? JSON.stringify(task, null, 2) : `Task not found: ${id}`, }, ], details: undefined, }; }, }; const listMissions: ToolDefinition = { name: 'brain_list_missions', label: 'List Missions', description: 'List all missions, optionally filtered by project.', parameters: Type.Object({ projectId: Type.Optional(Type.String({ description: 'Filter by project ID' })), }), async execute(_toolCallId, params) { const p = params as { projectId?: string }; const missions = p.projectId ? await brain.missions.findByProject(p.projectId) : await brain.missions.findAll(); return { content: [{ type: 'text' as const, text: JSON.stringify(missions, null, 2) }], details: undefined, }; }, }; const listConversations: ToolDefinition = { name: 'brain_list_conversations', label: 'List Conversations', description: 'List conversations for a user.', parameters: Type.Object({ userId: Type.String({ description: 'User ID' }), }), async execute(_toolCallId, params) { const { userId } = params as { userId: string }; const conversations = await brain.conversations.findAll(userId); return { content: [{ type: 'text' as const, text: JSON.stringify(conversations, null, 2) }], details: undefined, }; }, }; return [ listProjects, getProject, listTasks, createTask, updateTask, listMissions, listConversations, ]; }