Skip to content

Commit 2872e96

Browse files
committed
Decoupling of mcp tools
1 parent b195aae commit 2872e96

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+9304
-0
lines changed

src/tools/API_REFERENCE.md

Lines changed: 1082 additions & 0 deletions
Large diffs are not rendered by default.

src/tools/IMPLEMENTATION_SUMMARY.md

Lines changed: 517 additions & 0 deletions
Large diffs are not rendered by default.

src/tools/MIGRATION_GUIDE.md

Lines changed: 701 additions & 0 deletions
Large diffs are not rendered by default.

src/tools/README.md

Lines changed: 454 additions & 0 deletions
Large diffs are not rendered by default.

src/tools/USAGE_EXAMPLES.md

Lines changed: 890 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* Copyright (c) 2021-2025 Datalayer, Inc.
3+
*
4+
* MIT License
5+
*/
6+
7+
/**
8+
* ag-ui/CopilotKit Tool Adapter
9+
*
10+
* Converts unified tool definitions to CopilotKit's useCopilotAction format.
11+
*
12+
* @module tools/adapters/agui/AgUIToolAdapter
13+
*/
14+
15+
import type { ToolDefinition } from "../../definitions/schema";
16+
import type { ToolOperation } from "../../core/interfaces";
17+
import type { SaaSToolContext } from "../saas/SaaSToolContext";
18+
import { SaaSToolAdapter } from "../saas/SaaSToolAdapter";
19+
20+
/**
21+
* CopilotKit action definition (matches useCopilotAction interface)
22+
*/
23+
export interface CopilotKitAction {
24+
/** Action name (tool identifier) */
25+
name: string;
26+
27+
/** Human-readable description for AI model */
28+
description: string;
29+
30+
/** JSON Schema for parameters */
31+
parameters: {
32+
type: "object";
33+
properties: Record<string, unknown>;
34+
required?: string[];
35+
};
36+
37+
/** Handler function that executes the action */
38+
handler: (params: any) => Promise<string>;
39+
40+
/** Optional: Render function for custom UI */
41+
render?: (props: { status: string; args: any; result: any }) => React.ReactNode;
42+
}
43+
44+
/**
45+
* Converts a unified tool definition to CopilotKit action format
46+
*
47+
* @param definition - Unified tool definition
48+
* @param operation - Core operation implementation
49+
* @param context - SaaS tool context (reuses SaaS document handle)
50+
* @returns CopilotKit action ready for useCopilotAction
51+
*/
52+
export function createCopilotKitAction(
53+
definition: ToolDefinition,
54+
operation: ToolOperation<any, any>,
55+
context: SaaSToolContext,
56+
): CopilotKitAction {
57+
// Create SaaS adapter (ag-ui runs in browser, same as SaaS)
58+
const adapter = new SaaSToolAdapter(definition, operation, context);
59+
60+
return {
61+
name: definition.toolReferenceName || definition.name,
62+
description: definition.description,
63+
parameters: {
64+
type: "object",
65+
properties: definition.parameters.properties,
66+
required: definition.parameters.required,
67+
},
68+
69+
handler: async (params: any): Promise<string> => {
70+
try {
71+
const result = await adapter.execute(params);
72+
73+
// Format result as string for CopilotKit
74+
if (typeof result === "object" && result !== null) {
75+
const resultObj = result as any;
76+
77+
// Return success message if available
78+
if (resultObj.message) {
79+
return resultObj.message;
80+
}
81+
82+
// Return error if failed
83+
if (resultObj.success === false && resultObj.error) {
84+
return `❌ Error: ${resultObj.error}`;
85+
}
86+
87+
// Otherwise format as JSON
88+
return JSON.stringify(result, null, 2);
89+
}
90+
91+
return String(result);
92+
} catch (error) {
93+
const errorMessage =
94+
error instanceof Error ? error.message : String(error);
95+
return `❌ Error: ${errorMessage}`;
96+
}
97+
},
98+
99+
// Optional: Custom render function for ag-ui
100+
render: definition.platformConfig?.agui?.renderingHints?.customRender
101+
? (definition.platformConfig.agui.renderingHints.customRender as any)
102+
: undefined,
103+
};
104+
}
105+
106+
/**
107+
* Creates all CopilotKit actions from tool definitions
108+
*
109+
* @param definitions - Array of tool definitions
110+
* @param operations - Registry of core operations
111+
* @param context - SaaS tool context
112+
* @returns Array of CopilotKit actions
113+
*/
114+
export function createAllCopilotKitActions(
115+
definitions: ToolDefinition[],
116+
operations: Record<string, ToolOperation<any, any>>,
117+
context: SaaSToolContext,
118+
): CopilotKitAction[] {
119+
const actions: CopilotKitAction[] = [];
120+
121+
for (const definition of definitions) {
122+
const operation = operations[definition.operation];
123+
124+
if (!operation) {
125+
console.warn(
126+
`[ag-ui Tools] No operation found for ${definition.name} (operation: ${definition.operation})`,
127+
);
128+
continue;
129+
}
130+
131+
const action = createCopilotKitAction(definition, operation, context);
132+
actions.push(action);
133+
}
134+
135+
console.log(`[ag-ui Tools] Created ${actions.length} CopilotKit actions`);
136+
137+
return actions;
138+
}

src/tools/adapters/agui/hooks.tsx

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*
2+
* Copyright (c) 2021-2025 Datalayer, Inc.
3+
*
4+
* MIT License
5+
*/
6+
7+
/**
8+
* React hooks for ag-ui tool registration
9+
*
10+
* @module tools/adapters/agui/hooks
11+
*/
12+
13+
import { useEffect, useMemo } from "react";
14+
import type { ToolDefinition } from "../../definitions/schema";
15+
import type { ToolOperation } from "../../core/interfaces";
16+
import type { SaaSToolContext } from "../saas/SaaSToolContext";
17+
import { createAllCopilotKitActions } from "./AgUIToolAdapter";
18+
19+
// Type for useCopilotAction (from @copilotkit/react-core)
20+
type UseCopilotActionFn = (action: {
21+
name: string;
22+
description: string;
23+
parameters: any;
24+
handler: (params: any) => Promise<string>;
25+
render?: (props: any) => any;
26+
}) => void;
27+
28+
/**
29+
* React hook that automatically registers all Datalayer tools with CopilotKit
30+
*
31+
* This hook converts unified tool definitions to CopilotKit actions and
32+
* registers them using useCopilotAction.
33+
*
34+
* @param definitions - Array of tool definitions (defaults to all)
35+
* @param operations - Registry of core operations (defaults to all)
36+
* @param context - SaaS tool context (required)
37+
* @param useCopilotAction - CopilotKit's useCopilotAction hook
38+
*
39+
* @example
40+
* ```typescript
41+
* import { useCopilotAction } from '@copilotkit/react-core';
42+
* import { useNotebookTools } from './tools/adapters/agui';
43+
*
44+
* function NotebookEditor() {
45+
* const context = useSaaSToolContext(); // Your context hook
46+
*
47+
* // Auto-register all notebook tools with CopilotKit
48+
* useNotebookTools(context, useCopilotAction);
49+
*
50+
* return <YourNotebookUI />;
51+
* }
52+
* ```
53+
*/
54+
export function useNotebookTools(
55+
context: SaaSToolContext,
56+
useCopilotAction: UseCopilotActionFn,
57+
definitions?: ToolDefinition[],
58+
operations?: Record<string, ToolOperation<any, any>>,
59+
): void {
60+
// Import defaults if not provided
61+
const { allToolDefinitions } = require("../../definitions/tools");
62+
const { allOperations } = require("../../core/operations");
63+
64+
const toolDefinitions = definitions || allToolDefinitions;
65+
const toolOperations = operations || allOperations;
66+
67+
// Create CopilotKit actions from definitions
68+
const actions = useMemo(
69+
() => createAllCopilotKitActions(toolDefinitions, toolOperations, context),
70+
[toolDefinitions, toolOperations, context],
71+
);
72+
73+
// Register each action with CopilotKit
74+
useEffect(() => {
75+
console.log(
76+
`[ag-ui Tools] Registering ${actions.length} tools with CopilotKit`,
77+
);
78+
79+
actions.forEach((action) => {
80+
useCopilotAction(action);
81+
console.log(`[ag-ui Tools] ✓ Registered ${action.name}`);
82+
});
83+
84+
return () => {
85+
console.log("[ag-ui Tools] Cleanup (if needed)");
86+
};
87+
}, [actions, useCopilotAction]);
88+
}
89+
90+
/**
91+
* React hook that registers a single tool with CopilotKit
92+
*
93+
* Use this for selective tool registration or custom tools.
94+
*
95+
* @example
96+
* ```typescript
97+
* import { useSingleTool } from './tools/adapters/agui';
98+
*
99+
* function MyComponent() {
100+
* const context = useSaaSToolContext();
101+
*
102+
* // Register only insertCell tool
103+
* useSingleTool(insertCellTool, insertCellOperation, context, useCopilotAction);
104+
*
105+
* return <UI />;
106+
* }
107+
* ```
108+
*/
109+
export function useSingleTool(
110+
definition: ToolDefinition,
111+
operation: ToolOperation<any, any>,
112+
context: SaaSToolContext,
113+
useCopilotAction: UseCopilotActionFn,
114+
): void {
115+
const action = useMemo(
116+
() => {
117+
const { createCopilotKitAction } = require("./AgUIToolAdapter");
118+
return createCopilotKitAction(definition, operation, context);
119+
},
120+
[definition, operation, context],
121+
);
122+
123+
useEffect(() => {
124+
console.log(`[ag-ui Tools] Registering ${action.name}`);
125+
useCopilotAction(action);
126+
127+
return () => {
128+
console.log(`[ag-ui Tools] Cleanup for ${action.name}`);
129+
};
130+
}, [action, useCopilotAction]);
131+
}
132+
133+
/**
134+
* React hook that provides tool actions without auto-registration
135+
*
136+
* Use this when you want manual control over registration or need
137+
* to inspect actions before registering.
138+
*
139+
* @returns Array of CopilotKit actions ready for registration
140+
*
141+
* @example
142+
* ```typescript
143+
* function MyComponent() {
144+
* const context = useSaaSToolContext();
145+
* const actions = useToolActions(context);
146+
*
147+
* // Manually register specific actions
148+
* actions.filter(a => a.name.includes('cell')).forEach(useCopilotAction);
149+
*
150+
* return <UI />;
151+
* }
152+
* ```
153+
*/
154+
export function useToolActions(
155+
context: SaaSToolContext,
156+
definitions?: ToolDefinition[],
157+
operations?: Record<string, ToolOperation<any, any>>,
158+
): ReturnType<typeof createAllCopilotKitActions> {
159+
const { allToolDefinitions } = require("../../definitions/tools");
160+
const { allOperations } = require("../../core/operations");
161+
162+
const toolDefinitions = definitions || allToolDefinitions;
163+
const toolOperations = operations || allOperations;
164+
165+
return useMemo(
166+
() => createAllCopilotKitActions(toolDefinitions, toolOperations, context),
167+
[toolDefinitions, toolOperations, context],
168+
);
169+
}

src/tools/adapters/agui/index.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright (c) 2021-2025 Datalayer, Inc.
3+
*
4+
* MIT License
5+
*/
6+
7+
/**
8+
* ag-ui/CopilotKit Adapter Module
9+
*
10+
* Provides ag-ui (CopilotKit) integration for the unified tool architecture.
11+
*
12+
* @module tools/adapters/agui
13+
*/
14+
15+
export * from "./AgUIToolAdapter";
16+
export * from "./hooks";

0 commit comments

Comments
 (0)