Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
185 lines
6.1 KiB
TypeScript
185 lines
6.1 KiB
TypeScript
import { Type } from '@sinclair/typebox';
|
|
import type { ToolDefinition } from '@mariozechner/pi-coding-agent';
|
|
import type { Brain } from '@mosaic/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,
|
|
];
|
|
}
|