feat(api): add audit helpers, tool registry, shared tool manifest types, and UI primitives

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-09 21:14:26 +02:00
parent 1a67af6761
commit 43de66e982
8 changed files with 904 additions and 0 deletions
@@ -0,0 +1,134 @@
import type { ToolManifest } from "@capakraken/shared";
/**
* Rich metadata registry for AI assistant tools.
* Complements the OpenAI function schema (ToolDef) with category, mutation flag,
* and intent descriptions that improve model tool selection and documentation.
*
* Start: 10 high-traffic tools. Add entries as needed — the registry is additive
* and does not affect tool execution.
*/
export const TOOL_REGISTRY: ToolManifest[] = [
// ─── Planning ──────────────────────────────────────────────────────────────
{
name: "create_allocation",
category: "planning",
isMutation: true,
intent: "Assign a resource to a project for a specific date range at a utilization percentage",
examples: [
"Book Alice on Project X from April to June at 80%",
"Assign the lead developer to the backend project starting next Monday at full capacity",
],
},
{
name: "cancel_allocation",
category: "planning",
isMutation: true,
intent: "Remove a resource booking from a project",
examples: [
"Cancel Bob's allocation on Project Y",
"Remove the allocation for resource 123 on the frontend project",
],
},
{
name: "list_allocations",
category: "planning",
isMutation: false,
intent: "List all allocations for a project or resource within a date range",
examples: [
"Show me all bookings for the Alpha project this quarter",
"What projects is Alice allocated to in May?",
],
},
// ─── Resource ──────────────────────────────────────────────────────────────
{
name: "search_resources",
category: "resource",
isMutation: false,
intent: "Search for resources by name, skill, chapter, or seniority",
examples: [
"Find all senior developers in the Berlin chapter",
"Who has React skills and is available next month?",
],
},
{
name: "check_resource_availability",
category: "resource",
isMutation: false,
intent: "Check how many hours a resource has free in a date range",
examples: [
"Is Alice available for a new project in Q3?",
"How much capacity does the frontend chapter have next month?",
],
},
// ─── Staffing ──────────────────────────────────────────────────────────────
{
name: "get_staffing_suggestions",
category: "staffing",
isMutation: false,
requiresAdvanced: true,
intent: "Get ranked resource suggestions for an open demand, scored by skill match, availability, and cost",
examples: [
"Who should I assign to fill the senior designer role on Project Z?",
"Find the best available backend engineers for a 3-month engagement starting in June",
],
},
{
name: "fill_demand",
category: "staffing",
isMutation: true,
intent: "Create an allocation to fill an open staffing demand",
examples: [
"Fill the open designer demand with Alice",
"Assign Bob to satisfy the pending backend demand",
],
},
// ─── Vacation ──────────────────────────────────────────────────────────────
{
name: "create_vacation",
category: "vacation",
isMutation: true,
intent: "Submit a vacation or leave request for a resource",
examples: [
"Request 2 weeks of annual leave for Alice starting August 1st",
"Book sick leave for Bob for today",
],
},
{
name: "approve_vacation",
category: "vacation",
isMutation: true,
intent: "Approve a pending vacation request",
examples: [
"Approve Alice's vacation request",
"Accept the leave request with ID abc123",
],
},
// ─── Reporting ─────────────────────────────────────────────────────────────
{
name: "get_chargeability_report",
category: "reporting",
isMutation: false,
requiresAdvanced: true,
intent: "Generate a chargeability report showing billable vs. non-billable utilization across resources or chapters",
examples: [
"Show me chargeability for the engineering chapter in Q1",
"What is the billable rate for the team last month?",
],
},
];
/** Lookup map for O(1) manifest access by tool name. */
export const TOOL_REGISTRY_MAP: ReadonlyMap<string, ToolManifest> = new Map(
TOOL_REGISTRY.map((m) => [m.name, m]),
);
/** Get the manifest for a given tool name, or undefined if not registered. */
export function getToolManifest(name: string): ToolManifest | undefined {
return TOOL_REGISTRY_MAP.get(name);
}
/** Filter the registry by category. */
export function getToolsByCategory(category: ToolManifest["category"]): ToolManifest[] {
return TOOL_REGISTRY.filter((m) => m.category === category);
}