chore(repo): checkpoint current capakraken implementation state
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* AI Assistant router — provides a chat endpoint that uses OpenAI Function Calling
|
||||
* to answer questions about plANARCHY data and modify resources/projects.
|
||||
* to answer questions about CapaKraken data and modify resources/projects.
|
||||
*/
|
||||
|
||||
import { z } from "zod";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { AssistantApprovalStatus, type PrismaClient } from "@capakraken/db";
|
||||
import { PermissionKey, resolvePermissions, type PermissionOverrides, type SystemRole } from "@capakraken/shared";
|
||||
import { PermissionKey, resolvePermissions, type PermissionOverrides, SystemRole } from "@capakraken/shared";
|
||||
import { createTRPCRouter, protectedProcedure } from "../trpc.js";
|
||||
import { createAiClient, isAiConfigured, loggedAiCall, parseAiError } from "../ai-client.js";
|
||||
import { ADVANCED_ASSISTANT_TOOLS, MUTATION_TOOLS, TOOL_DEFINITIONS, executeTool, type ToolContext, type ToolAction } from "./assistant-tools.js";
|
||||
@@ -112,6 +112,11 @@ const TOOL_PERMISSION_MAP: Record<string, string> = {
|
||||
create_allocation: "manageAllocations",
|
||||
cancel_allocation: "manageAllocations",
|
||||
update_allocation_status: "manageAllocations",
|
||||
update_timeline_allocation_inline: "manageAllocations",
|
||||
apply_timeline_project_shift: "manageAllocations",
|
||||
quick_assign_timeline_resource: "manageAllocations",
|
||||
batch_quick_assign_timeline_resources: "manageAllocations",
|
||||
batch_shift_timeline_allocations: "manageAllocations",
|
||||
create_demand: "manageAllocations",
|
||||
fill_demand: "manageAllocations",
|
||||
// Vacation management
|
||||
@@ -127,16 +132,71 @@ const TOOL_PERMISSION_MAP: Record<string, string> = {
|
||||
};
|
||||
|
||||
/** Tools that require cost visibility */
|
||||
const COST_TOOLS = new Set(["get_budget_status", "get_chargeability", "resolve_rate", "list_rate_cards", "get_estimate_detail", "find_best_project_resource"]);
|
||||
const COST_TOOLS = new Set([
|
||||
"get_budget_status",
|
||||
"get_chargeability",
|
||||
"get_chargeability_report",
|
||||
"get_resource_computation_graph",
|
||||
"get_project_computation_graph",
|
||||
"resolve_rate",
|
||||
"list_rate_cards",
|
||||
"get_estimate_detail",
|
||||
"find_best_project_resource",
|
||||
]);
|
||||
|
||||
export function getAvailableAssistantTools(permissions: Set<PermissionKey>) {
|
||||
/** Tools that follow controllerProcedure access rules in the main API. */
|
||||
const CONTROLLER_ONLY_TOOLS = new Set([
|
||||
"get_chargeability_report",
|
||||
"get_resource_computation_graph",
|
||||
"get_project_computation_graph",
|
||||
]);
|
||||
|
||||
/** Tools that follow managerProcedure access rules in the main API. */
|
||||
const MANAGER_ONLY_TOOLS = new Set([
|
||||
"update_timeline_allocation_inline",
|
||||
"apply_timeline_project_shift",
|
||||
"quick_assign_timeline_resource",
|
||||
"batch_quick_assign_timeline_resources",
|
||||
"batch_shift_timeline_allocations",
|
||||
]);
|
||||
|
||||
/** Tools that are intentionally limited to ADMIN because the backing routers are admin-only today. */
|
||||
const ADMIN_ONLY_TOOLS = new Set([
|
||||
"create_country",
|
||||
"update_country",
|
||||
"create_metro_city",
|
||||
"update_metro_city",
|
||||
"delete_metro_city",
|
||||
"create_holiday_calendar",
|
||||
"update_holiday_calendar",
|
||||
"delete_holiday_calendar",
|
||||
"create_holiday_calendar_entry",
|
||||
"update_holiday_calendar_entry",
|
||||
"delete_holiday_calendar_entry",
|
||||
]);
|
||||
|
||||
export function getAvailableAssistantTools(permissions: Set<PermissionKey>, userRole: string) {
|
||||
return TOOL_DEFINITIONS.filter((tool) => {
|
||||
const toolName = tool.function.name;
|
||||
const requiredPerm = TOOL_PERMISSION_MAP[toolName];
|
||||
const hasControllerAccess = userRole === SystemRole.ADMIN
|
||||
|| userRole === SystemRole.MANAGER
|
||||
|| userRole === SystemRole.CONTROLLER;
|
||||
const hasManagerAccess = userRole === SystemRole.ADMIN
|
||||
|| userRole === SystemRole.MANAGER;
|
||||
|
||||
if (requiredPerm && !permissions.has(requiredPerm as PermissionKey)) {
|
||||
return false;
|
||||
}
|
||||
if (ADMIN_ONLY_TOOLS.has(toolName) && userRole !== "ADMIN") {
|
||||
return false;
|
||||
}
|
||||
if (MANAGER_ONLY_TOOLS.has(toolName) && !hasManagerAccess) {
|
||||
return false;
|
||||
}
|
||||
if (CONTROLLER_ONLY_TOOLS.has(toolName) && !hasControllerAccess) {
|
||||
return false;
|
||||
}
|
||||
if (COST_TOOLS.has(toolName) && !permissions.has(PermissionKey.VIEW_COSTS)) {
|
||||
return false;
|
||||
}
|
||||
@@ -597,7 +657,7 @@ export const assistantRouter = createTRPCRouter({
|
||||
}
|
||||
|
||||
// 4. Filter tools based on granular permissions
|
||||
const availableTools = getAvailableAssistantTools(permissions);
|
||||
const availableTools = getAvailableAssistantTools(permissions, userRole);
|
||||
|
||||
// 5. Function calling loop
|
||||
const toolCtx: ToolContext = {
|
||||
|
||||
Reference in New Issue
Block a user