Spaces:
Running
Running
Commit
·
67c6e06
1
Parent(s):
3a61a4f
feat: implement sandbox management and MCP client integration
Browse files- Added functionality to start and stop sandboxes for executing commands in isolated environments.
- Integrated MCP client management for handling server connections and tool initialization.
- Enhanced the chat route to generate titles for new chats and manage server states.
- Updated the MCP server manager component to include server control actions and status indicators.
- Introduced a new context for managing MCP server states and sandbox references.
- Improved error handling and logging for better debugging and user feedback.
- app/actions.ts +98 -0
- app/api/chat/route.ts +59 -132
- components/mcp-server-manager.tsx +147 -18
- lib/context/mcp-context.tsx +191 -10
- lib/mcp-client.ts +105 -0
- lib/mcp-sandbox.ts +101 -0
- package.json +8 -7
- pnpm-lock.yaml +363 -48
app/actions.ts
CHANGED
@@ -3,6 +3,11 @@
|
|
3 |
import { openai } from "@ai-sdk/openai";
|
4 |
import { generateObject } from "ai";
|
5 |
import { z } from "zod";
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
// Helper to extract text content from a message regardless of format
|
8 |
function getMessageText(message: any): string {
|
@@ -64,3 +69,96 @@ export async function generateTitle(messages: any[]) {
|
|
64 |
|
65 |
return object.title;
|
66 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
import { openai } from "@ai-sdk/openai";
|
4 |
import { generateObject } from "ai";
|
5 |
import { z } from "zod";
|
6 |
+
import { startMcpSandbox } from '@/lib/mcp-sandbox';
|
7 |
+
|
8 |
+
// Use a global map to store active sandbox instances across requests
|
9 |
+
const activeSandboxes = (global as any).activeSandboxes || new Map();
|
10 |
+
(global as any).activeSandboxes = activeSandboxes;
|
11 |
|
12 |
// Helper to extract text content from a message regardless of format
|
13 |
function getMessageText(message: any): string {
|
|
|
69 |
|
70 |
return object.title;
|
71 |
}
|
72 |
+
|
73 |
+
export interface KeyValuePair {
|
74 |
+
key: string;
|
75 |
+
value: string;
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Server action to start a sandbox
|
80 |
+
*/
|
81 |
+
export async function startSandbox(params: {
|
82 |
+
id: string;
|
83 |
+
command: string;
|
84 |
+
args: string[];
|
85 |
+
env?: KeyValuePair[];
|
86 |
+
}): Promise<{ url: string }> {
|
87 |
+
const { id, command, args, env } = params;
|
88 |
+
|
89 |
+
// Validate required fields
|
90 |
+
if (!id || !command || !args) {
|
91 |
+
throw new Error('Missing required fields');
|
92 |
+
}
|
93 |
+
|
94 |
+
// Check if we already have a sandbox for this ID
|
95 |
+
if (activeSandboxes.has(id)) {
|
96 |
+
// If we do, get the URL and return it without creating a new sandbox
|
97 |
+
const existingSandbox = activeSandboxes.get(id);
|
98 |
+
return { url: existingSandbox.url };
|
99 |
+
}
|
100 |
+
|
101 |
+
// Build the command string
|
102 |
+
let cmd: string;
|
103 |
+
|
104 |
+
// Prepare the command based on the type of executable
|
105 |
+
if (command === 'uvx') {
|
106 |
+
// For uvx, use the direct format
|
107 |
+
const toolName = args[0];
|
108 |
+
cmd = `uvx ${toolName} ${args.slice(1).join(' ')}`;
|
109 |
+
} else if (command.includes('python')) {
|
110 |
+
// For python commands
|
111 |
+
cmd = `${command} ${args.join(' ')}`;
|
112 |
+
} else {
|
113 |
+
// For node or other commands
|
114 |
+
cmd = `${command} ${args.join(' ')}`;
|
115 |
+
}
|
116 |
+
|
117 |
+
// Convert env array to object if needed
|
118 |
+
const envs: Record<string, string> = {};
|
119 |
+
if (env && env.length > 0) {
|
120 |
+
env.forEach((envVar) => {
|
121 |
+
if (envVar.key) envs[envVar.key] = envVar.value || '';
|
122 |
+
});
|
123 |
+
}
|
124 |
+
|
125 |
+
// Start the sandbox
|
126 |
+
console.log(`Starting sandbox for ${id} with command: ${cmd}`);
|
127 |
+
const sandbox = await startMcpSandbox({ cmd, envs });
|
128 |
+
const url = await sandbox.getUrl();
|
129 |
+
|
130 |
+
// Store the sandbox in our map
|
131 |
+
activeSandboxes.set(id, { sandbox, url });
|
132 |
+
|
133 |
+
return { url };
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Server action to stop a sandbox
|
138 |
+
*/
|
139 |
+
export async function stopSandbox(id: string): Promise<{ success: boolean }> {
|
140 |
+
if (!id) {
|
141 |
+
throw new Error('Missing sandbox ID');
|
142 |
+
}
|
143 |
+
|
144 |
+
// Check if we have a sandbox with this ID
|
145 |
+
if (!activeSandboxes.has(id)) {
|
146 |
+
throw new Error(`No active sandbox found with ID: ${id}`);
|
147 |
+
}
|
148 |
+
|
149 |
+
// Stop the sandbox
|
150 |
+
const { sandbox } = activeSandboxes.get(id);
|
151 |
+
|
152 |
+
try {
|
153 |
+
await sandbox.stop();
|
154 |
+
console.log(`Stopped sandbox with ID: ${id}`);
|
155 |
+
} catch (stopError) {
|
156 |
+
console.error(`Error stopping sandbox ${id}:`, stopError);
|
157 |
+
// Continue to remove from the map even if stop fails
|
158 |
+
}
|
159 |
+
|
160 |
+
// Remove from our map
|
161 |
+
activeSandboxes.delete(id);
|
162 |
+
|
163 |
+
return { success: true };
|
164 |
+
}
|
app/api/chat/route.ts
CHANGED
@@ -1,32 +1,20 @@
|
|
1 |
import { model, type modelID } from "@/ai/providers";
|
2 |
-
import { streamText, type UIMessage } from "ai";
|
3 |
import { appendResponseMessages } from 'ai';
|
4 |
import { saveChat, saveMessages, convertToDBMessages } from '@/lib/chat-store';
|
5 |
import { nanoid } from 'nanoid';
|
6 |
import { db } from '@/lib/db';
|
7 |
import { chats } from '@/lib/db/schema';
|
8 |
import { eq, and } from 'drizzle-orm';
|
|
|
|
|
9 |
|
10 |
-
|
11 |
-
import { Experimental_StdioMCPTransport as StdioMCPTransport } from 'ai/mcp-stdio';
|
12 |
-
import { spawn } from "child_process";
|
13 |
|
14 |
// Allow streaming responses up to 30 seconds
|
15 |
export const maxDuration = 120;
|
16 |
|
17 |
-
|
18 |
-
key: string;
|
19 |
-
value: string;
|
20 |
-
}
|
21 |
-
|
22 |
-
interface MCPServerConfig {
|
23 |
-
url: string;
|
24 |
-
type: 'sse' | 'stdio';
|
25 |
-
command?: string;
|
26 |
-
args?: string[];
|
27 |
-
env?: KeyValuePair[];
|
28 |
-
headers?: KeyValuePair[];
|
29 |
-
}
|
30 |
|
31 |
export async function POST(req: Request) {
|
32 |
const {
|
@@ -53,7 +41,7 @@ export async function POST(req: Request) {
|
|
53 |
const id = chatId || nanoid();
|
54 |
|
55 |
// Check if chat already exists for the given ID
|
56 |
-
// If not,
|
57 |
let isNewChat = false;
|
58 |
if (chatId) {
|
59 |
try {
|
@@ -66,7 +54,6 @@ export async function POST(req: Request) {
|
|
66 |
isNewChat = !existingChat;
|
67 |
} catch (error) {
|
68 |
console.error("Error checking for existing chat:", error);
|
69 |
-
// Continue anyway, we'll create the chat in onFinish
|
70 |
isNewChat = true;
|
71 |
}
|
72 |
} else {
|
@@ -74,125 +61,44 @@ export async function POST(req: Request) {
|
|
74 |
isNewChat = true;
|
75 |
}
|
76 |
|
77 |
-
//
|
78 |
-
|
79 |
-
const mcpClients: any[] = [];
|
80 |
-
|
81 |
-
// Process each MCP server configuration
|
82 |
-
for (const mcpServer of mcpServers) {
|
83 |
try {
|
84 |
-
//
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
});
|
94 |
-
}
|
95 |
-
|
96 |
-
transport = {
|
97 |
-
type: 'sse' as const,
|
98 |
-
url: mcpServer.url,
|
99 |
-
headers: Object.keys(headers).length > 0 ? headers : undefined
|
100 |
-
};
|
101 |
-
} else if (mcpServer.type === 'stdio') {
|
102 |
-
// For stdio transport, we need command and args
|
103 |
-
if (!mcpServer.command || !mcpServer.args || mcpServer.args.length === 0) {
|
104 |
-
console.warn("Skipping stdio MCP server due to missing command or args");
|
105 |
-
continue;
|
106 |
-
}
|
107 |
-
|
108 |
-
// Convert env array to object for stdio transport
|
109 |
-
const env: Record<string, string> = {};
|
110 |
-
if (mcpServer.env && mcpServer.env.length > 0) {
|
111 |
-
mcpServer.env.forEach(envVar => {
|
112 |
-
if (envVar.key) env[envVar.key] = envVar.value || '';
|
113 |
-
});
|
114 |
-
}
|
115 |
-
|
116 |
-
// Check for uvx pattern and transform to python3 -m uv run
|
117 |
-
if (mcpServer.command === 'uvx') {
|
118 |
-
// install uv
|
119 |
-
const subprocess = spawn('pip3', ['install', 'uv']);
|
120 |
-
subprocess.on('close', (code: number) => {
|
121 |
-
if (code !== 0) {
|
122 |
-
console.error(`Failed to install uv: ${code}`);
|
123 |
-
}
|
124 |
-
});
|
125 |
-
// wait for the subprocess to finish
|
126 |
-
await new Promise((resolve) => {
|
127 |
-
subprocess.on('close', resolve);
|
128 |
-
console.log("installed uv");
|
129 |
-
});
|
130 |
-
console.log("Detected uvx pattern, transforming to python3 -m uv run");
|
131 |
-
mcpServer.command = 'python3';
|
132 |
-
// Get the tool name (first argument)
|
133 |
-
const toolName = mcpServer.args[0];
|
134 |
-
// Replace args with the new pattern
|
135 |
-
mcpServer.args = ['-m', 'uv', 'run', toolName, ...mcpServer.args.slice(1)];
|
136 |
-
}
|
137 |
-
// if python is passed in the command, install the python package mentioned in args after -m with subprocess or use regex to find the package name
|
138 |
-
else if (mcpServer.command.includes('python3')) {
|
139 |
-
const packageName = mcpServer.args[mcpServer.args.indexOf('-m') + 1];
|
140 |
-
console.log("installing python package", packageName);
|
141 |
-
const subprocess = spawn('pip3', ['install', packageName]);
|
142 |
-
subprocess.on('close', (code: number) => {
|
143 |
-
if (code !== 0) {
|
144 |
-
console.error(`Failed to install python package: ${code}`);
|
145 |
-
}
|
146 |
-
});
|
147 |
-
// wait for the subprocess to finish
|
148 |
-
await new Promise((resolve) => {
|
149 |
-
subprocess.on('close', resolve);
|
150 |
-
console.log("installed python package", packageName);
|
151 |
-
});
|
152 |
}
|
153 |
-
|
154 |
-
transport = new StdioMCPTransport({
|
155 |
-
command: mcpServer.command,
|
156 |
-
args: mcpServer.args,
|
157 |
-
env: Object.keys(env).length > 0 ? env : undefined
|
158 |
-
});
|
159 |
-
} else {
|
160 |
-
console.warn(`Skipping MCP server with unsupported transport type: ${mcpServer.type}`);
|
161 |
-
continue;
|
162 |
}
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
// Add MCP tools to tools object
|
172 |
-
tools = { ...tools, ...mcptools };
|
173 |
} catch (error) {
|
174 |
-
console.error("
|
175 |
-
// Continue with other servers instead of failing the entire request
|
176 |
}
|
177 |
}
|
178 |
|
179 |
-
//
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
try {
|
184 |
-
await client.close();
|
185 |
-
} catch (error) {
|
186 |
-
console.error("Error closing MCP client:", error);
|
187 |
-
}
|
188 |
-
}
|
189 |
-
});
|
190 |
-
}
|
191 |
|
192 |
console.log("messages", messages);
|
193 |
console.log("parts", messages.map(m => m.parts.map(p => p)));
|
194 |
|
195 |
-
//
|
|
|
|
|
196 |
const result = streamText({
|
197 |
model: model.languageModel(selectedModel),
|
198 |
system: `You are a helpful assistant with access to a variety of tools.
|
@@ -233,10 +139,15 @@ export async function POST(req: Request) {
|
|
233 |
},
|
234 |
}
|
235 |
},
|
|
|
|
|
|
|
|
|
236 |
onError: (error) => {
|
237 |
console.error(JSON.stringify(error, null, 2));
|
238 |
},
|
239 |
async onFinish({ response }) {
|
|
|
240 |
const allMessages = appendResponseMessages({
|
241 |
messages,
|
242 |
responseMessages: response.messages,
|
@@ -250,16 +161,32 @@ export async function POST(req: Request) {
|
|
250 |
|
251 |
const dbMessages = convertToDBMessages(allMessages, id);
|
252 |
await saveMessages({ messages: dbMessages });
|
253 |
-
|
254 |
-
//
|
255 |
-
//
|
256 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
257 |
}
|
258 |
});
|
259 |
|
260 |
result.consumeStream()
|
|
|
261 |
return result.toDataStreamResponse({
|
262 |
sendReasoning: true,
|
|
|
|
|
|
|
263 |
getErrorMessage: (error) => {
|
264 |
if (error instanceof Error) {
|
265 |
if (error.message.includes("Rate limit")) {
|
@@ -270,4 +197,4 @@ export async function POST(req: Request) {
|
|
270 |
return "An error occurred.";
|
271 |
},
|
272 |
});
|
273 |
-
}
|
|
|
1 |
import { model, type modelID } from "@/ai/providers";
|
2 |
+
import { smoothStream, streamText, type UIMessage } from "ai";
|
3 |
import { appendResponseMessages } from 'ai';
|
4 |
import { saveChat, saveMessages, convertToDBMessages } from '@/lib/chat-store';
|
5 |
import { nanoid } from 'nanoid';
|
6 |
import { db } from '@/lib/db';
|
7 |
import { chats } from '@/lib/db/schema';
|
8 |
import { eq, and } from 'drizzle-orm';
|
9 |
+
import { initializeMCPClients, type MCPServerConfig } from '@/lib/mcp-client';
|
10 |
+
import { generateTitle } from '@/app/actions';
|
11 |
|
12 |
+
export const runtime = 'nodejs';
|
|
|
|
|
13 |
|
14 |
// Allow streaming responses up to 30 seconds
|
15 |
export const maxDuration = 120;
|
16 |
|
17 |
+
export const dynamic = 'force-dynamic';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
export async function POST(req: Request) {
|
20 |
const {
|
|
|
41 |
const id = chatId || nanoid();
|
42 |
|
43 |
// Check if chat already exists for the given ID
|
44 |
+
// If not, create it now
|
45 |
let isNewChat = false;
|
46 |
if (chatId) {
|
47 |
try {
|
|
|
54 |
isNewChat = !existingChat;
|
55 |
} catch (error) {
|
56 |
console.error("Error checking for existing chat:", error);
|
|
|
57 |
isNewChat = true;
|
58 |
}
|
59 |
} else {
|
|
|
61 |
isNewChat = true;
|
62 |
}
|
63 |
|
64 |
+
// If it's a new chat, save it immediately
|
65 |
+
if (isNewChat && messages.length > 0) {
|
|
|
|
|
|
|
|
|
66 |
try {
|
67 |
+
// Generate a title based on first user message
|
68 |
+
const userMessage = messages.find(m => m.role === 'user');
|
69 |
+
let title = 'New Chat';
|
70 |
+
|
71 |
+
if (userMessage) {
|
72 |
+
try {
|
73 |
+
title = await generateTitle([userMessage]);
|
74 |
+
} catch (error) {
|
75 |
+
console.error("Error generating title:", error);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
}
|
78 |
+
|
79 |
+
// Save the chat immediately so it appears in the sidebar
|
80 |
+
await saveChat({
|
81 |
+
id,
|
82 |
+
userId,
|
83 |
+
title,
|
84 |
+
messages: [],
|
85 |
+
});
|
|
|
|
|
86 |
} catch (error) {
|
87 |
+
console.error("Error saving new chat:", error);
|
|
|
88 |
}
|
89 |
}
|
90 |
|
91 |
+
// Initialize MCP clients using the already running persistent SSE servers
|
92 |
+
// mcpServers now only contains SSE configurations since stdio servers
|
93 |
+
// have been converted to SSE in the MCP context
|
94 |
+
const { tools, cleanup } = await initializeMCPClients(mcpServers, req.signal);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
|
96 |
console.log("messages", messages);
|
97 |
console.log("parts", messages.map(m => m.parts.map(p => p)));
|
98 |
|
99 |
+
// Track if the response has completed
|
100 |
+
let responseCompleted = false;
|
101 |
+
|
102 |
const result = streamText({
|
103 |
model: model.languageModel(selectedModel),
|
104 |
system: `You are a helpful assistant with access to a variety of tools.
|
|
|
139 |
},
|
140 |
}
|
141 |
},
|
142 |
+
experimental_transform: smoothStream({
|
143 |
+
delayInMs: 5, // optional: defaults to 10ms
|
144 |
+
chunking: 'line', // optional: defaults to 'word'
|
145 |
+
}),
|
146 |
onError: (error) => {
|
147 |
console.error(JSON.stringify(error, null, 2));
|
148 |
},
|
149 |
async onFinish({ response }) {
|
150 |
+
responseCompleted = true;
|
151 |
const allMessages = appendResponseMessages({
|
152 |
messages,
|
153 |
responseMessages: response.messages,
|
|
|
161 |
|
162 |
const dbMessages = convertToDBMessages(allMessages, id);
|
163 |
await saveMessages({ messages: dbMessages });
|
164 |
+
|
165 |
+
// Clean up resources - now this just closes the client connections
|
166 |
+
// not the actual servers which persist in the MCP context
|
167 |
+
await cleanup();
|
168 |
+
}
|
169 |
+
});
|
170 |
+
|
171 |
+
// Ensure cleanup happens if the request is terminated early
|
172 |
+
req.signal.addEventListener('abort', async () => {
|
173 |
+
if (!responseCompleted) {
|
174 |
+
console.log("Request aborted, cleaning up resources");
|
175 |
+
try {
|
176 |
+
await cleanup();
|
177 |
+
} catch (error) {
|
178 |
+
console.error("Error during cleanup on abort:", error);
|
179 |
+
}
|
180 |
}
|
181 |
});
|
182 |
|
183 |
result.consumeStream()
|
184 |
+
// Add chat ID to response headers so client can know which chat was created
|
185 |
return result.toDataStreamResponse({
|
186 |
sendReasoning: true,
|
187 |
+
headers: {
|
188 |
+
'X-Chat-ID': id
|
189 |
+
},
|
190 |
getErrorMessage: (error) => {
|
191 |
if (error instanceof Error) {
|
192 |
if (error.message.includes("Rate limit")) {
|
|
|
197 |
return "An error occurred.";
|
198 |
},
|
199 |
});
|
200 |
+
}
|
components/mcp-server-manager.tsx
CHANGED
@@ -24,7 +24,10 @@ import {
|
|
24 |
Cog,
|
25 |
Edit2,
|
26 |
Eye,
|
27 |
-
EyeOff
|
|
|
|
|
|
|
28 |
} from "lucide-react";
|
29 |
import { toast } from "sonner";
|
30 |
import {
|
@@ -33,7 +36,7 @@ import {
|
|
33 |
AccordionItem,
|
34 |
AccordionTrigger
|
35 |
} from "./ui/accordion";
|
36 |
-
import { KeyValuePair, MCPServer } from "@/lib/context/mcp-context";
|
37 |
|
38 |
// Default template for a new MCP server
|
39 |
const INITIAL_NEW_SERVER: Omit<MCPServer, 'id'> = {
|
@@ -76,6 +79,44 @@ const maskValue = (value: string): string => {
|
|
76 |
return value.substring(0, 3) + '•'.repeat(Math.min(10, value.length - 4)) + value.substring(value.length - 1);
|
77 |
};
|
78 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
export const MCPServerManager = ({
|
80 |
servers,
|
81 |
onServersChange,
|
@@ -95,6 +136,9 @@ export const MCPServerManager = ({
|
|
95 |
const [editingHeaderIndex, setEditingHeaderIndex] = useState<number | null>(null);
|
96 |
const [editedEnvValue, setEditedEnvValue] = useState<string>('');
|
97 |
const [editedHeaderValue, setEditedHeaderValue] = useState<string>('');
|
|
|
|
|
|
|
98 |
|
99 |
const resetAndClose = () => {
|
100 |
setView('list');
|
@@ -356,6 +400,57 @@ export const MCPServerManager = ({
|
|
356 |
setShowSensitiveHeaderValues({});
|
357 |
};
|
358 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
359 |
return (
|
360 |
<Dialog open={open} onOpenChange={onOpenChange}>
|
361 |
<DialogContent className="sm:max-w-[480px] max-h-[85vh] overflow-hidden flex flex-col">
|
@@ -396,6 +491,8 @@ export const MCPServerManager = ({
|
|
396 |
})
|
397 |
.map((server) => {
|
398 |
const isActive = selectedServers.includes(server.id);
|
|
|
|
|
399 |
return (
|
400 |
<div
|
401 |
key={server.id}
|
@@ -406,7 +503,7 @@ export const MCPServerManager = ({
|
|
406 |
: 'border-border hover:border-primary/30 hover:bg-primary/5'}
|
407 |
`}
|
408 |
>
|
409 |
-
{/* Server Header with Type Badge and
|
410 |
<div className="flex items-center justify-between mb-2">
|
411 |
<div className="flex items-center gap-2">
|
412 |
{server.type === 'sse' ? (
|
@@ -414,7 +511,7 @@ export const MCPServerManager = ({
|
|
414 |
) : (
|
415 |
<Terminal className={`h-4 w-4 ${isActive ? 'text-primary' : 'text-muted-foreground'} flex-shrink-0`} />
|
416 |
)}
|
417 |
-
<h4 className="text-sm font-medium truncate max-w-[
|
418 |
{hasAdvancedConfig(server) && (
|
419 |
<span className="flex-shrink-0">
|
420 |
<Cog className="h-3 w-3 text-muted-foreground" />
|
@@ -425,20 +522,52 @@ export const MCPServerManager = ({
|
|
425 |
<span className="text-xs px-2 py-0.5 rounded-full bg-secondary text-secondary-foreground">
|
426 |
{server.type.toUpperCase()}
|
427 |
</span>
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
442 |
</div>
|
443 |
</div>
|
444 |
|
|
|
24 |
Cog,
|
25 |
Edit2,
|
26 |
Eye,
|
27 |
+
EyeOff,
|
28 |
+
AlertTriangle,
|
29 |
+
RefreshCw,
|
30 |
+
Power
|
31 |
} from "lucide-react";
|
32 |
import { toast } from "sonner";
|
33 |
import {
|
|
|
36 |
AccordionItem,
|
37 |
AccordionTrigger
|
38 |
} from "./ui/accordion";
|
39 |
+
import { KeyValuePair, MCPServer, ServerStatus, useMCP } from "@/lib/context/mcp-context";
|
40 |
|
41 |
// Default template for a new MCP server
|
42 |
const INITIAL_NEW_SERVER: Omit<MCPServer, 'id'> = {
|
|
|
79 |
return value.substring(0, 3) + '•'.repeat(Math.min(10, value.length - 4)) + value.substring(value.length - 1);
|
80 |
};
|
81 |
|
82 |
+
const StatusIndicator = ({ status, onClick }: { status?: ServerStatus, onClick?: () => void }) => {
|
83 |
+
const isClickable = !!onClick;
|
84 |
+
|
85 |
+
const className = `flex-shrink-0 flex items-center gap-1 ${isClickable ? 'cursor-pointer hover:underline' : ''}`;
|
86 |
+
|
87 |
+
switch (status) {
|
88 |
+
case 'connected':
|
89 |
+
return (
|
90 |
+
<div className={className} onClick={onClick}>
|
91 |
+
<div className="w-2 h-2 rounded-full bg-green-500 animate-pulse" />
|
92 |
+
<span className="text-xs text-green-500">Connected</span>
|
93 |
+
</div>
|
94 |
+
);
|
95 |
+
case 'connecting':
|
96 |
+
return (
|
97 |
+
<div className={className} onClick={onClick}>
|
98 |
+
<RefreshCw className="w-3 h-3 text-amber-500 animate-spin" />
|
99 |
+
<span className="text-xs text-amber-500">Connecting</span>
|
100 |
+
</div>
|
101 |
+
);
|
102 |
+
case 'error':
|
103 |
+
return (
|
104 |
+
<div className={className} onClick={onClick}>
|
105 |
+
<AlertTriangle className="w-3 h-3 text-red-500" />
|
106 |
+
<span className="text-xs text-red-500">Error</span>
|
107 |
+
</div>
|
108 |
+
);
|
109 |
+
case 'disconnected':
|
110 |
+
default:
|
111 |
+
return (
|
112 |
+
<div className={className} onClick={onClick}>
|
113 |
+
<div className="w-2 h-2 rounded-full bg-gray-400" />
|
114 |
+
<span className="text-xs text-muted-foreground">Disconnected</span>
|
115 |
+
</div>
|
116 |
+
);
|
117 |
+
}
|
118 |
+
};
|
119 |
+
|
120 |
export const MCPServerManager = ({
|
121 |
servers,
|
122 |
onServersChange,
|
|
|
136 |
const [editingHeaderIndex, setEditingHeaderIndex] = useState<number | null>(null);
|
137 |
const [editedEnvValue, setEditedEnvValue] = useState<string>('');
|
138 |
const [editedHeaderValue, setEditedHeaderValue] = useState<string>('');
|
139 |
+
|
140 |
+
// Add access to the MCP context for server control
|
141 |
+
const { startServer, stopServer, updateServerStatus } = useMCP();
|
142 |
|
143 |
const resetAndClose = () => {
|
144 |
setView('list');
|
|
|
400 |
setShowSensitiveHeaderValues({});
|
401 |
};
|
402 |
|
403 |
+
// Add functions to control servers
|
404 |
+
const toggleServerStatus = async (server: MCPServer, e: React.MouseEvent) => {
|
405 |
+
e.stopPropagation();
|
406 |
+
|
407 |
+
if (!server.status || server.status === 'disconnected' || server.status === 'error') {
|
408 |
+
// Start the server
|
409 |
+
try {
|
410 |
+
const success = await startServer(server.id);
|
411 |
+
if (success) {
|
412 |
+
toast.success(`Started server: ${server.name}`);
|
413 |
+
} else {
|
414 |
+
toast.error(`Failed to start server: ${server.name}`);
|
415 |
+
}
|
416 |
+
} catch (error) {
|
417 |
+
toast.error(`Error starting server: ${error instanceof Error ? error.message : String(error)}`);
|
418 |
+
}
|
419 |
+
} else {
|
420 |
+
// Stop the server
|
421 |
+
try {
|
422 |
+
await stopServer(server.id);
|
423 |
+
toast.success(`Stopped server: ${server.name}`);
|
424 |
+
} catch (error) {
|
425 |
+
toast.error(`Error stopping server: ${error instanceof Error ? error.message : String(error)}`);
|
426 |
+
}
|
427 |
+
}
|
428 |
+
};
|
429 |
+
|
430 |
+
// Add function to restart a server
|
431 |
+
const restartServer = async (server: MCPServer, e: React.MouseEvent) => {
|
432 |
+
e.stopPropagation();
|
433 |
+
|
434 |
+
try {
|
435 |
+
// First stop it if it's running
|
436 |
+
if (server.status === 'connected' || server.status === 'connecting') {
|
437 |
+
await stopServer(server.id);
|
438 |
+
}
|
439 |
+
|
440 |
+
// Then start it again
|
441 |
+
updateServerStatus(server.id, 'connecting');
|
442 |
+
const success = await startServer(server.id);
|
443 |
+
|
444 |
+
if (success) {
|
445 |
+
toast.success(`Restarted server: ${server.name}`);
|
446 |
+
} else {
|
447 |
+
toast.error(`Failed to restart server: ${server.name}`);
|
448 |
+
}
|
449 |
+
} catch (error) {
|
450 |
+
toast.error(`Error restarting server: ${error instanceof Error ? error.message : String(error)}`);
|
451 |
+
}
|
452 |
+
};
|
453 |
+
|
454 |
return (
|
455 |
<Dialog open={open} onOpenChange={onOpenChange}>
|
456 |
<DialogContent className="sm:max-w-[480px] max-h-[85vh] overflow-hidden flex flex-col">
|
|
|
491 |
})
|
492 |
.map((server) => {
|
493 |
const isActive = selectedServers.includes(server.id);
|
494 |
+
const isRunning = server.status === 'connected' || server.status === 'connecting';
|
495 |
+
|
496 |
return (
|
497 |
<div
|
498 |
key={server.id}
|
|
|
503 |
: 'border-border hover:border-primary/30 hover:bg-primary/5'}
|
504 |
`}
|
505 |
>
|
506 |
+
{/* Server Header with Type Badge and Actions */}
|
507 |
<div className="flex items-center justify-between mb-2">
|
508 |
<div className="flex items-center gap-2">
|
509 |
{server.type === 'sse' ? (
|
|
|
511 |
) : (
|
512 |
<Terminal className={`h-4 w-4 ${isActive ? 'text-primary' : 'text-muted-foreground'} flex-shrink-0`} />
|
513 |
)}
|
514 |
+
<h4 className="text-sm font-medium truncate max-w-[160px]">{server.name}</h4>
|
515 |
{hasAdvancedConfig(server) && (
|
516 |
<span className="flex-shrink-0">
|
517 |
<Cog className="h-3 w-3 text-muted-foreground" />
|
|
|
522 |
<span className="text-xs px-2 py-0.5 rounded-full bg-secondary text-secondary-foreground">
|
523 |
{server.type.toUpperCase()}
|
524 |
</span>
|
525 |
+
|
526 |
+
{/* Status indicator */}
|
527 |
+
<StatusIndicator
|
528 |
+
status={server.status}
|
529 |
+
onClick={() => server.errorMessage && toast.error(server.errorMessage)}
|
530 |
+
/>
|
531 |
+
|
532 |
+
{/* Server actions */}
|
533 |
+
<div className="flex items-center">
|
534 |
+
<button
|
535 |
+
onClick={(e) => toggleServerStatus(server, e)}
|
536 |
+
className="p-1 rounded-full hover:bg-muted/70"
|
537 |
+
aria-label={isRunning ? "Stop server" : "Start server"}
|
538 |
+
title={isRunning ? "Stop server" : "Start server"}
|
539 |
+
>
|
540 |
+
<Power className={`h-3.5 w-3.5 ${isRunning ? 'text-red-500' : 'text-green-500'}`} />
|
541 |
+
</button>
|
542 |
+
|
543 |
+
<button
|
544 |
+
onClick={(e) => restartServer(server, e)}
|
545 |
+
className="p-1 rounded-full hover:bg-muted/70"
|
546 |
+
aria-label="Restart server"
|
547 |
+
title="Restart server"
|
548 |
+
disabled={server.status === 'connecting'}
|
549 |
+
>
|
550 |
+
<RefreshCw className={`h-3.5 w-3.5 text-muted-foreground ${server.status === 'connecting' ? 'opacity-50' : ''}`} />
|
551 |
+
</button>
|
552 |
+
|
553 |
+
<button
|
554 |
+
onClick={(e) => removeServer(server.id, e)}
|
555 |
+
className="p-1 rounded-full hover:bg-muted/70"
|
556 |
+
aria-label="Remove server"
|
557 |
+
title="Remove server"
|
558 |
+
>
|
559 |
+
<Trash2 className="h-3.5 w-3.5 text-muted-foreground" />
|
560 |
+
</button>
|
561 |
+
|
562 |
+
<button
|
563 |
+
onClick={() => startEditing(server)}
|
564 |
+
className="p-1 rounded-full hover:bg-muted/50"
|
565 |
+
aria-label="Edit server"
|
566 |
+
title="Edit server"
|
567 |
+
>
|
568 |
+
<Edit2 className="h-3.5 w-3.5 text-muted-foreground" />
|
569 |
+
</button>
|
570 |
+
</div>
|
571 |
</div>
|
572 |
</div>
|
573 |
|
lib/context/mcp-context.tsx
CHANGED
@@ -1,8 +1,9 @@
|
|
1 |
"use client";
|
2 |
|
3 |
-
import React, { createContext, useContext, useEffect, useState } from "react";
|
4 |
import { useLocalStorage } from "@/lib/hooks/use-local-storage";
|
5 |
import { STORAGE_KEYS } from "@/lib/constants";
|
|
|
6 |
|
7 |
// Define types for MCP server
|
8 |
export interface KeyValuePair {
|
@@ -10,6 +11,8 @@ export interface KeyValuePair {
|
|
10 |
value: string;
|
11 |
}
|
12 |
|
|
|
|
|
13 |
export interface MCPServer {
|
14 |
id: string;
|
15 |
name: string;
|
@@ -20,28 +23,54 @@ export interface MCPServer {
|
|
20 |
env?: KeyValuePair[];
|
21 |
headers?: KeyValuePair[];
|
22 |
description?: string;
|
|
|
|
|
23 |
}
|
24 |
|
25 |
// Type for processed MCP server config for API
|
26 |
export interface MCPServerApi {
|
27 |
-
type: 'sse'
|
28 |
url: string;
|
29 |
-
command?: string;
|
30 |
-
args?: string[];
|
31 |
-
env?: KeyValuePair[];
|
32 |
headers?: KeyValuePair[];
|
33 |
}
|
34 |
|
|
|
|
|
|
|
|
|
|
|
35 |
interface MCPContextType {
|
36 |
mcpServers: MCPServer[];
|
37 |
setMcpServers: (servers: MCPServer[]) => void;
|
38 |
selectedMcpServers: string[];
|
39 |
setSelectedMcpServers: (serverIds: string[]) => void;
|
40 |
mcpServersForApi: MCPServerApi[];
|
|
|
|
|
|
|
41 |
}
|
42 |
|
43 |
const MCPContext = createContext<MCPContextType | undefined>(undefined);
|
44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
export function MCPProvider(props: { children: React.ReactNode }) {
|
46 |
const { children } = props;
|
47 |
const [mcpServers, setMcpServers] = useLocalStorage<MCPServer[]>(
|
@@ -53,6 +82,157 @@ export function MCPProvider(props: { children: React.ReactNode }) {
|
|
53 |
[]
|
54 |
);
|
55 |
const [mcpServersForApi, setMcpServersForApi] = useState<MCPServerApi[]>([]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
|
57 |
// Process MCP servers for API consumption whenever server data changes
|
58 |
useEffect(() => {
|
@@ -65,11 +245,9 @@ export function MCPProvider(props: { children: React.ReactNode }) {
|
|
65 |
.map(id => mcpServers.find(server => server.id === id))
|
66 |
.filter((server): server is MCPServer => Boolean(server))
|
67 |
.map(server => ({
|
68 |
-
type
|
|
|
69 |
url: server.url,
|
70 |
-
command: server.command,
|
71 |
-
args: server.args,
|
72 |
-
env: server.env,
|
73 |
headers: server.headers
|
74 |
}));
|
75 |
|
@@ -83,7 +261,10 @@ export function MCPProvider(props: { children: React.ReactNode }) {
|
|
83 |
setMcpServers,
|
84 |
selectedMcpServers,
|
85 |
setSelectedMcpServers,
|
86 |
-
mcpServersForApi
|
|
|
|
|
|
|
87 |
}}
|
88 |
>
|
89 |
{children}
|
|
|
1 |
"use client";
|
2 |
|
3 |
+
import React, { createContext, useContext, useEffect, useState, useRef } from "react";
|
4 |
import { useLocalStorage } from "@/lib/hooks/use-local-storage";
|
5 |
import { STORAGE_KEYS } from "@/lib/constants";
|
6 |
+
import { startSandbox, stopSandbox } from "@/app/actions";
|
7 |
|
8 |
// Define types for MCP server
|
9 |
export interface KeyValuePair {
|
|
|
11 |
value: string;
|
12 |
}
|
13 |
|
14 |
+
export type ServerStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
|
15 |
+
|
16 |
export interface MCPServer {
|
17 |
id: string;
|
18 |
name: string;
|
|
|
23 |
env?: KeyValuePair[];
|
24 |
headers?: KeyValuePair[];
|
25 |
description?: string;
|
26 |
+
status?: ServerStatus;
|
27 |
+
errorMessage?: string;
|
28 |
}
|
29 |
|
30 |
// Type for processed MCP server config for API
|
31 |
export interface MCPServerApi {
|
32 |
+
type: 'sse';
|
33 |
url: string;
|
|
|
|
|
|
|
34 |
headers?: KeyValuePair[];
|
35 |
}
|
36 |
|
37 |
+
interface SandboxInfo {
|
38 |
+
id: string;
|
39 |
+
url: string;
|
40 |
+
}
|
41 |
+
|
42 |
interface MCPContextType {
|
43 |
mcpServers: MCPServer[];
|
44 |
setMcpServers: (servers: MCPServer[]) => void;
|
45 |
selectedMcpServers: string[];
|
46 |
setSelectedMcpServers: (serverIds: string[]) => void;
|
47 |
mcpServersForApi: MCPServerApi[];
|
48 |
+
startServer: (serverId: string) => Promise<boolean>;
|
49 |
+
stopServer: (serverId: string) => Promise<void>;
|
50 |
+
updateServerStatus: (serverId: string, status: ServerStatus, errorMessage?: string) => void;
|
51 |
}
|
52 |
|
53 |
const MCPContext = createContext<MCPContextType | undefined>(undefined);
|
54 |
|
55 |
+
// Helper function to wait for server readiness
|
56 |
+
async function waitForServerReady(url: string, maxAttempts = 15) {
|
57 |
+
for (let i = 0; i < maxAttempts; i++) {
|
58 |
+
try {
|
59 |
+
const response = await fetch(url);
|
60 |
+
if (response.status === 200) {
|
61 |
+
console.log(`Server ready at ${url} after ${i + 1} attempts`);
|
62 |
+
return true;
|
63 |
+
}
|
64 |
+
console.log(`Server not ready yet (attempt ${i + 1}), status: ${response.status}`);
|
65 |
+
} catch {
|
66 |
+
console.log(`Server connection failed (attempt ${i + 1})`);
|
67 |
+
}
|
68 |
+
// Wait between attempts
|
69 |
+
await new Promise(resolve => setTimeout(resolve, 6000));
|
70 |
+
}
|
71 |
+
return false;
|
72 |
+
}
|
73 |
+
|
74 |
export function MCPProvider(props: { children: React.ReactNode }) {
|
75 |
const { children } = props;
|
76 |
const [mcpServers, setMcpServers] = useLocalStorage<MCPServer[]>(
|
|
|
82 |
[]
|
83 |
);
|
84 |
const [mcpServersForApi, setMcpServersForApi] = useState<MCPServerApi[]>([]);
|
85 |
+
|
86 |
+
// Keep a ref to active sandboxes (only their IDs and URLs)
|
87 |
+
const sandboxesRef = useRef<SandboxInfo[]>([]);
|
88 |
+
|
89 |
+
// Update server status
|
90 |
+
const updateServerStatus = (serverId: string, status: ServerStatus, errorMessage?: string) => {
|
91 |
+
setMcpServers(current =>
|
92 |
+
current.map(server =>
|
93 |
+
server.id === serverId
|
94 |
+
? { ...server, status, errorMessage: errorMessage || undefined }
|
95 |
+
: server
|
96 |
+
)
|
97 |
+
);
|
98 |
+
};
|
99 |
+
|
100 |
+
// Start a server (if it's stdio type) using server actions
|
101 |
+
const startServer = async (serverId: string): Promise<boolean> => {
|
102 |
+
const server = mcpServers.find(s => s.id === serverId);
|
103 |
+
if (!server) return false;
|
104 |
+
|
105 |
+
// If it's already an SSE server, just update the status
|
106 |
+
if (server.type === 'sse') {
|
107 |
+
updateServerStatus(serverId, 'connecting');
|
108 |
+
|
109 |
+
try {
|
110 |
+
const isReady = await waitForServerReady(server.url);
|
111 |
+
updateServerStatus(serverId, isReady ? 'connected' : 'error',
|
112 |
+
isReady ? undefined : 'Could not connect to server');
|
113 |
+
return isReady;
|
114 |
+
} catch (error) {
|
115 |
+
updateServerStatus(serverId, 'error', `Connection error: ${error instanceof Error ? error.message : String(error)}`);
|
116 |
+
return false;
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
// For stdio type, start a sandbox via the server action
|
121 |
+
if (server.type === 'stdio' && server.command && server.args?.length) {
|
122 |
+
updateServerStatus(serverId, 'connecting');
|
123 |
+
|
124 |
+
try {
|
125 |
+
// Check if we already have a sandbox for this server
|
126 |
+
const existingSandbox = sandboxesRef.current.find(s => s.id === serverId);
|
127 |
+
if (existingSandbox) {
|
128 |
+
try {
|
129 |
+
// Test if the existing sandbox is still responsive
|
130 |
+
const isReady = await waitForServerReady(existingSandbox.url);
|
131 |
+
if (isReady) {
|
132 |
+
updateServerStatus(serverId, 'connected');
|
133 |
+
return true;
|
134 |
+
}
|
135 |
+
// If not responsive, we'll create a new one below
|
136 |
+
} catch {
|
137 |
+
// Sandbox wasn't responsive, continue to create a new one
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
// Call the server action to create a sandbox
|
142 |
+
const { url } = await startSandbox({
|
143 |
+
id: serverId,
|
144 |
+
command: server.command,
|
145 |
+
args: server.args,
|
146 |
+
env: server.env,
|
147 |
+
});
|
148 |
+
|
149 |
+
// Wait for the server to become ready
|
150 |
+
const isReady = await waitForServerReady(url);
|
151 |
+
if (!isReady) {
|
152 |
+
updateServerStatus(serverId, 'error', 'Server failed to start in time');
|
153 |
+
|
154 |
+
// Attempt to stop the sandbox since it's not working correctly
|
155 |
+
try {
|
156 |
+
await stopSandbox(serverId);
|
157 |
+
} catch (stopError) {
|
158 |
+
console.error('Failed to stop non-responsive sandbox:', stopError);
|
159 |
+
}
|
160 |
+
|
161 |
+
return false;
|
162 |
+
}
|
163 |
+
|
164 |
+
// Store the sandbox reference
|
165 |
+
// Remove any existing sandbox for this server first
|
166 |
+
sandboxesRef.current = sandboxesRef.current.filter(s => s.id !== serverId);
|
167 |
+
sandboxesRef.current.push({ id: serverId, url });
|
168 |
+
|
169 |
+
// Update the server URL to point to the sandbox SSE URL
|
170 |
+
setMcpServers(current =>
|
171 |
+
current.map(s =>
|
172 |
+
s.id === serverId
|
173 |
+
? { ...s, status: 'connected', errorMessage: undefined, url }
|
174 |
+
: s
|
175 |
+
)
|
176 |
+
);
|
177 |
+
|
178 |
+
return true;
|
179 |
+
} catch (error) {
|
180 |
+
console.error('Error starting server:', error);
|
181 |
+
updateServerStatus(serverId, 'error', `Startup error: ${error instanceof Error ? error.message : String(error)}`);
|
182 |
+
return false;
|
183 |
+
}
|
184 |
+
}
|
185 |
+
|
186 |
+
return false;
|
187 |
+
};
|
188 |
+
|
189 |
+
// Stop a server using the server action
|
190 |
+
const stopServer = async (serverId: string): Promise<void> => {
|
191 |
+
// Find the sandbox for this server
|
192 |
+
const sandboxIndex = sandboxesRef.current.findIndex(s => s.id === serverId);
|
193 |
+
if (sandboxIndex >= 0) {
|
194 |
+
try {
|
195 |
+
// Call server action to stop the sandbox
|
196 |
+
await stopSandbox(serverId);
|
197 |
+
console.log(`Stopped sandbox for server ${serverId}`);
|
198 |
+
} catch (error) {
|
199 |
+
console.error(`Error stopping sandbox for server ${serverId}:`, error);
|
200 |
+
}
|
201 |
+
|
202 |
+
// Remove from our tracking
|
203 |
+
sandboxesRef.current.splice(sandboxIndex, 1);
|
204 |
+
}
|
205 |
+
|
206 |
+
// Update server status
|
207 |
+
updateServerStatus(serverId, 'disconnected');
|
208 |
+
};
|
209 |
+
|
210 |
+
// Auto-start selected servers when they're added to the selection
|
211 |
+
useEffect(() => {
|
212 |
+
const startSelectedServers = async () => {
|
213 |
+
for (const serverId of selectedMcpServers) {
|
214 |
+
const server = mcpServers.find(s => s.id === serverId);
|
215 |
+
if (server && (!server.status || server.status === 'disconnected')) {
|
216 |
+
await startServer(serverId);
|
217 |
+
}
|
218 |
+
}
|
219 |
+
};
|
220 |
+
|
221 |
+
startSelectedServers();
|
222 |
+
|
223 |
+
// Cleanup on unmount
|
224 |
+
return () => {
|
225 |
+
// Stop all running sandboxes
|
226 |
+
sandboxesRef.current.forEach(async ({ id }) => {
|
227 |
+
try {
|
228 |
+
await stopSandbox(id);
|
229 |
+
} catch (error) {
|
230 |
+
console.error('Error stopping sandbox during cleanup:', error);
|
231 |
+
}
|
232 |
+
});
|
233 |
+
sandboxesRef.current = [];
|
234 |
+
};
|
235 |
+
}, [selectedMcpServers]);
|
236 |
|
237 |
// Process MCP servers for API consumption whenever server data changes
|
238 |
useEffect(() => {
|
|
|
245 |
.map(id => mcpServers.find(server => server.id === id))
|
246 |
.filter((server): server is MCPServer => Boolean(server))
|
247 |
.map(server => ({
|
248 |
+
// All servers are exposed as SSE type to the API
|
249 |
+
type: 'sse',
|
250 |
url: server.url,
|
|
|
|
|
|
|
251 |
headers: server.headers
|
252 |
}));
|
253 |
|
|
|
261 |
setMcpServers,
|
262 |
selectedMcpServers,
|
263 |
setSelectedMcpServers,
|
264 |
+
mcpServersForApi,
|
265 |
+
startServer,
|
266 |
+
stopServer,
|
267 |
+
updateServerStatus
|
268 |
}}
|
269 |
>
|
270 |
{children}
|
lib/mcp-client.ts
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { experimental_createMCPClient as createMCPClient } from 'ai';
|
2 |
+
|
3 |
+
|
4 |
+
export interface KeyValuePair {
|
5 |
+
key: string;
|
6 |
+
value: string;
|
7 |
+
}
|
8 |
+
|
9 |
+
export interface MCPServerConfig {
|
10 |
+
url: string;
|
11 |
+
type: 'sse' | 'stdio';
|
12 |
+
command?: string;
|
13 |
+
args?: string[];
|
14 |
+
env?: KeyValuePair[];
|
15 |
+
headers?: KeyValuePair[];
|
16 |
+
}
|
17 |
+
|
18 |
+
export interface MCPClientManager {
|
19 |
+
tools: Record<string, any>;
|
20 |
+
clients: any[];
|
21 |
+
cleanup: () => Promise<void>;
|
22 |
+
}
|
23 |
+
|
24 |
+
async function waitForServerReady(url: string, maxAttempts = 5) {
|
25 |
+
for (let i = 0; i < maxAttempts; i++) {
|
26 |
+
try {
|
27 |
+
const response = await fetch(url)
|
28 |
+
if (response.status === 200) {
|
29 |
+
console.log(`Server ready at ${url} after ${i + 1} attempts`)
|
30 |
+
return true
|
31 |
+
}
|
32 |
+
console.log(`Server not ready yet (attempt ${i + 1}), status: ${response.status}`)
|
33 |
+
} catch {
|
34 |
+
console.log(`Server connection failed (attempt ${i + 1})`)
|
35 |
+
}
|
36 |
+
// Wait 6 seconds between attempts
|
37 |
+
await new Promise(resolve => setTimeout(resolve, 6000))
|
38 |
+
}
|
39 |
+
return false
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Initialize MCP clients for API calls
|
44 |
+
* This uses the already running persistent SSE servers
|
45 |
+
*/
|
46 |
+
export async function initializeMCPClients(
|
47 |
+
mcpServers: MCPServerConfig[] = [],
|
48 |
+
abortSignal?: AbortSignal
|
49 |
+
): Promise<MCPClientManager> {
|
50 |
+
// Initialize tools
|
51 |
+
let tools = {};
|
52 |
+
const mcpClients: any[] = [];
|
53 |
+
|
54 |
+
// Process each MCP server configuration
|
55 |
+
for (const mcpServer of mcpServers) {
|
56 |
+
try {
|
57 |
+
// All servers are handled as SSE
|
58 |
+
const transport = {
|
59 |
+
type: 'sse' as const,
|
60 |
+
url: mcpServer.url,
|
61 |
+
headers: mcpServer.headers?.reduce((acc, header) => {
|
62 |
+
if (header.key) acc[header.key] = header.value || '';
|
63 |
+
return acc;
|
64 |
+
}, {} as Record<string, string>)
|
65 |
+
};
|
66 |
+
|
67 |
+
const mcpClient = await createMCPClient({ transport });
|
68 |
+
mcpClients.push(mcpClient);
|
69 |
+
|
70 |
+
const mcptools = await mcpClient.tools();
|
71 |
+
|
72 |
+
console.log(`MCP tools from ${mcpServer.url}:`, Object.keys(mcptools));
|
73 |
+
|
74 |
+
// Add MCP tools to tools object
|
75 |
+
tools = { ...tools, ...mcptools };
|
76 |
+
} catch (error) {
|
77 |
+
console.error("Failed to initialize MCP client:", error);
|
78 |
+
// Continue with other servers instead of failing the entire request
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
// Register cleanup for all clients if an abort signal is provided
|
83 |
+
if (abortSignal && mcpClients.length > 0) {
|
84 |
+
abortSignal.addEventListener('abort', async () => {
|
85 |
+
await cleanupMCPClients(mcpClients);
|
86 |
+
});
|
87 |
+
}
|
88 |
+
|
89 |
+
return {
|
90 |
+
tools,
|
91 |
+
clients: mcpClients,
|
92 |
+
cleanup: async () => await cleanupMCPClients(mcpClients)
|
93 |
+
};
|
94 |
+
}
|
95 |
+
|
96 |
+
async function cleanupMCPClients(clients: any[]): Promise<void> {
|
97 |
+
// Clean up the MCP clients
|
98 |
+
for (const client of clients) {
|
99 |
+
try {
|
100 |
+
await client.close();
|
101 |
+
} catch (error) {
|
102 |
+
console.error("Error closing MCP client:", error);
|
103 |
+
}
|
104 |
+
}
|
105 |
+
}
|
lib/mcp-sandbox.ts
ADDED
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// import Sandbox from "@e2b/code-interpreter";
|
2 |
+
import { Daytona, Sandbox, SandboxTargetRegion } from "@daytonaio/sdk";
|
3 |
+
|
4 |
+
export const startMcpSandbox = async ({
|
5 |
+
cmd,
|
6 |
+
envs = {},
|
7 |
+
}: {
|
8 |
+
cmd: string
|
9 |
+
envs?: Record<string, string>
|
10 |
+
}) => {
|
11 |
+
console.log("Creating sandbox...");
|
12 |
+
const daytona = new Daytona();
|
13 |
+
const sandbox = await daytona.create({
|
14 |
+
resources: {
|
15 |
+
cpu: 2,
|
16 |
+
memory: 4,
|
17 |
+
disk: 5,
|
18 |
+
},
|
19 |
+
public: true,
|
20 |
+
autoStopInterval: 0, // 24 hours
|
21 |
+
timeout: 1000 * 300, // 5 minutes
|
22 |
+
envVars: {
|
23 |
+
...envs,
|
24 |
+
},
|
25 |
+
});
|
26 |
+
|
27 |
+
const host = await sandbox.getPreviewLink(3000);
|
28 |
+
const url = host.url;
|
29 |
+
const token = host.token;
|
30 |
+
console.log("url", url);
|
31 |
+
console.log("token", token);
|
32 |
+
|
33 |
+
const sessionId = Math.random().toString(36).substring(2, 30);
|
34 |
+
await sandbox.process.createSession(sessionId);
|
35 |
+
// python -m mcp_server_time --local-timezone=Asia/Kolkata
|
36 |
+
const isPythonCommand = cmd.startsWith('python') || cmd.startsWith('python3');
|
37 |
+
let installResult = null;
|
38 |
+
|
39 |
+
if (isPythonCommand) {
|
40 |
+
const packageName = cmd.split("-m ")[1]?.split(" ")[0] || "";
|
41 |
+
if (packageName) {
|
42 |
+
console.log(`Installing Python package: ${packageName}`);
|
43 |
+
const installUv = await sandbox.process.executeSessionCommand(sessionId, {
|
44 |
+
// Install python package from the command after -m in the command
|
45 |
+
command: `pip install ${packageName}`,
|
46 |
+
runAsync: true,
|
47 |
+
},
|
48 |
+
1000 * 300 // 5 minutes
|
49 |
+
);
|
50 |
+
console.log("install result", installUv.output);
|
51 |
+
if (installUv.exitCode !== 0) {
|
52 |
+
console.error("Failed to install package");
|
53 |
+
}
|
54 |
+
installResult = installUv;
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
console.log("Starting mcp server...");
|
59 |
+
// generate a session with random id
|
60 |
+
const mcpServer = await sandbox.process.executeSessionCommand(sessionId,
|
61 |
+
{
|
62 |
+
command: `npx -y supergateway --base-url ${url} --header "x-daytona-preview-token: ${token}" --port 3000 --cors --stdio "${cmd}"`,
|
63 |
+
runAsync: true,
|
64 |
+
},
|
65 |
+
1000 * 300 // 5 minutes
|
66 |
+
);
|
67 |
+
console.log("mcp server result", mcpServer.output);
|
68 |
+
const session = await sandbox.process.getSession(sessionId);
|
69 |
+
console.log(`Session ${sessionId}:`);
|
70 |
+
for (const command of session.commands || []) {
|
71 |
+
console.log(`Command: ${command.command}, Exit Code: ${command.exitCode}`);
|
72 |
+
}
|
73 |
+
if (mcpServer.exitCode !== 0) {
|
74 |
+
console.error("Failed to start mcp server. Exit code:", mcpServer.exitCode);
|
75 |
+
}
|
76 |
+
|
77 |
+
console.log("MCP server started at:", url + "/sse");
|
78 |
+
return new McpSandbox(sandbox);
|
79 |
+
}
|
80 |
+
|
81 |
+
class McpSandbox {
|
82 |
+
public sandbox: Sandbox;
|
83 |
+
|
84 |
+
constructor(sandbox: Sandbox) {
|
85 |
+
this.sandbox = sandbox;
|
86 |
+
}
|
87 |
+
|
88 |
+
async getUrl(): Promise<string> {
|
89 |
+
if (!this.sandbox) {
|
90 |
+
throw new Error("Sandbox not initialized");
|
91 |
+
}
|
92 |
+
const host = await this.sandbox.getPreviewLink(3000);
|
93 |
+
return `${host.url}/sse`;
|
94 |
+
}
|
95 |
+
|
96 |
+
async stop(): Promise<void> {
|
97 |
+
await this.sandbox.delete();
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
export type { McpSandbox };
|
package.json
CHANGED
@@ -13,13 +13,14 @@
|
|
13 |
"db:studio": "drizzle-kit studio"
|
14 |
},
|
15 |
"dependencies": {
|
16 |
-
"@ai-sdk/anthropic": "^1.2.
|
17 |
-
"@ai-sdk/
|
18 |
-
"@ai-sdk/
|
19 |
-
"@ai-sdk/
|
20 |
-
"@ai-sdk/
|
21 |
-
"@ai-sdk/
|
22 |
-
"@
|
|
|
23 |
"@neondatabase/serverless": "^1.0.0",
|
24 |
"@radix-ui/react-accordion": "^1.2.7",
|
25 |
"@radix-ui/react-avatar": "^1.1.6",
|
|
|
13 |
"db:studio": "drizzle-kit studio"
|
14 |
},
|
15 |
"dependencies": {
|
16 |
+
"@ai-sdk/anthropic": "^1.2.11",
|
17 |
+
"@ai-sdk/google": "^1.2.17",
|
18 |
+
"@ai-sdk/groq": "^1.2.9",
|
19 |
+
"@ai-sdk/openai": "^1.3.22",
|
20 |
+
"@ai-sdk/react": "^1.2.12",
|
21 |
+
"@ai-sdk/xai": "^1.2.16",
|
22 |
+
"@daytonaio/sdk": "^0.17.0",
|
23 |
+
"@e2b/code-interpreter": "^1.5.0",
|
24 |
"@neondatabase/serverless": "^1.0.0",
|
25 |
"@radix-ui/react-accordion": "^1.2.7",
|
26 |
"@radix-ui/react-avatar": "^1.1.6",
|
pnpm-lock.yaml
CHANGED
@@ -9,26 +9,29 @@ importers:
|
|
9 |
.:
|
10 |
dependencies:
|
11 |
'@ai-sdk/anthropic':
|
12 |
-
specifier: ^1.2.
|
13 |
-
version: 1.2.
|
14 |
-
'@ai-sdk/cohere':
|
15 |
-
specifier: ^1.2.9
|
16 |
-
version: 1.2.9([email protected])
|
17 |
'@ai-sdk/google':
|
18 |
-
specifier: ^1.2.
|
19 |
-
version: 1.2.
|
20 |
'@ai-sdk/groq':
|
21 |
-
specifier: ^1.2.
|
22 |
-
version: 1.2.
|
23 |
'@ai-sdk/openai':
|
24 |
-
specifier: ^1.3.
|
25 |
-
version: 1.3.
|
26 |
'@ai-sdk/react':
|
27 |
-
specifier: ^1.2.
|
28 |
-
version: 1.2.
|
29 |
'@ai-sdk/xai':
|
30 |
-
specifier: ^1.2.
|
31 |
-
version: 1.2.
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
'@neondatabase/serverless':
|
33 |
specifier: ^1.0.0
|
34 |
version: 1.0.0
|
@@ -186,44 +189,44 @@ importers:
|
|
186 |
|
187 |
packages:
|
188 |
|
189 |
-
'@ai-sdk/[email protected].
|
190 |
-
resolution: {integrity: sha512-
|
191 |
engines: {node: '>=18'}
|
192 |
peerDependencies:
|
193 |
zod: ^3.0.0
|
194 |
|
195 |
-
'@ai-sdk/
|
196 |
-
resolution: {integrity: sha512-
|
197 |
engines: {node: '>=18'}
|
198 |
peerDependencies:
|
199 |
zod: ^3.0.0
|
200 |
|
201 |
-
'@ai-sdk/
|
202 |
-
resolution: {integrity: sha512-
|
203 |
engines: {node: '>=18'}
|
204 |
peerDependencies:
|
205 |
zod: ^3.0.0
|
206 |
|
207 |
-
'@ai-sdk/
|
208 |
-
resolution: {integrity: sha512-
|
209 |
engines: {node: '>=18'}
|
210 |
peerDependencies:
|
211 |
zod: ^3.0.0
|
212 |
|
213 |
-
'@ai-sdk/openai
|
214 |
-
resolution: {integrity: sha512-
|
215 |
engines: {node: '>=18'}
|
216 |
peerDependencies:
|
217 |
zod: ^3.0.0
|
218 |
|
219 |
-
'@ai-sdk/
|
220 |
-
resolution: {integrity: sha512-
|
221 |
engines: {node: '>=18'}
|
222 |
peerDependencies:
|
223 |
-
zod: ^3.
|
224 |
|
225 |
-
'@ai-sdk/[email protected].
|
226 |
-
resolution: {integrity: sha512-
|
227 |
engines: {node: '>=18'}
|
228 |
peerDependencies:
|
229 |
zod: ^3.23.8
|
@@ -232,6 +235,16 @@ packages:
|
|
232 |
resolution: {integrity: sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg==}
|
233 |
engines: {node: '>=18'}
|
234 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
'@ai-sdk/[email protected]':
|
236 |
resolution: {integrity: sha512-/VYm8xifyngaqFDLXACk/1czDRCefNCdALUyp+kIX6DUIYUWTM93ISoZ+qJ8+3E+FiJAKBQz61o8lIIl+vYtzg==}
|
237 |
engines: {node: '>=18'}
|
@@ -242,14 +255,20 @@ packages:
|
|
242 |
zod:
|
243 |
optional: true
|
244 |
|
|
|
|
|
|
|
|
|
|
|
|
|
245 |
'@ai-sdk/[email protected]':
|
246 |
resolution: {integrity: sha512-nls/IJCY+ks3Uj6G/agNhXqQeLVqhNfoJbuNgCny+nX2veY5ADB91EcZUqVeQ/ionul2SeUswPY6Q/DxteY29Q==}
|
247 |
engines: {node: '>=18'}
|
248 |
peerDependencies:
|
249 |
zod: ^3.23.8
|
250 |
|
251 |
-
'@ai-sdk/[email protected].
|
252 |
-
resolution: {integrity: sha512-
|
253 |
engines: {node: '>=18'}
|
254 |
peerDependencies:
|
255 |
zod: ^3.0.0
|
@@ -262,12 +281,46 @@ packages:
|
|
262 |
resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==}
|
263 |
engines: {node: '>=6.9.0'}
|
264 |
|
|
|
|
|
|
|
265 |
'@cloudflare/[email protected]':
|
266 |
resolution: {integrity: sha512-uu8gZ8P6teFsyfJOIXBrNC4ZsjLWPUEMeDqbQCdJ8OA6Rs/8QoUYD7ZSLW2kxsO/6upcbZir1WGrWp8088aVWg==}
|
267 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
268 |
'@drizzle-team/[email protected]':
|
269 |
resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==}
|
270 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
271 |
'@emnapi/[email protected]':
|
272 |
resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==}
|
273 |
|
@@ -815,6 +868,18 @@ packages:
|
|
815 |
cpu: [x64]
|
816 |
os: [win32]
|
817 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
818 |
'@nodelib/[email protected]':
|
819 |
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
820 |
engines: {node: '>= 8'}
|
@@ -1827,6 +1892,9 @@ packages:
|
|
1827 |
resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==}
|
1828 |
engines: {node: '>=4'}
|
1829 |
|
|
|
|
|
|
|
1830 | |
1831 |
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
|
1832 |
engines: {node: '>= 0.4'}
|
@@ -1927,6 +1995,13 @@ packages:
|
|
1927 | |
1928 |
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
|
1929 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1930 | |
1931 |
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
1932 |
|
@@ -2113,6 +2188,14 @@ packages:
|
|
2113 |
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
2114 |
engines: {node: '>= 0.4'}
|
2115 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2116 | |
2117 |
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
|
2118 |
|
@@ -2298,6 +2381,10 @@ packages:
|
|
2298 |
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
2299 |
engines: {node: '>=6'}
|
2300 |
|
|
|
|
|
|
|
|
|
2301 | |
2302 |
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
|
2303 |
|
@@ -2348,6 +2435,15 @@ packages:
|
|
2348 | |
2349 |
resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
|
2350 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2351 | |
2352 |
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
|
2353 |
engines: {node: '>= 0.4'}
|
@@ -2399,6 +2495,10 @@ packages:
|
|
2399 |
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
|
2400 |
engines: {node: '>= 0.4'}
|
2401 |
|
|
|
|
|
|
|
|
|
2402 | |
2403 |
resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
|
2404 |
engines: {node: '>= 0.4'}
|
@@ -2471,6 +2571,10 @@ packages:
|
|
2471 | |
2472 |
resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
|
2473 |
|
|
|
|
|
|
|
|
|
2474 | |
2475 |
resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
|
2476 |
|
@@ -2587,6 +2691,10 @@ packages:
|
|
2587 |
resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==}
|
2588 |
engines: {node: '>= 0.4'}
|
2589 |
|
|
|
|
|
|
|
|
|
2590 | |
2591 |
resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==}
|
2592 |
engines: {node: '>= 0.4'}
|
@@ -2617,6 +2725,10 @@ packages:
|
|
2617 | |
2618 |
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
2619 |
|
|
|
|
|
|
|
|
|
2620 | |
2621 |
resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
|
2622 |
engines: {node: '>= 0.4'}
|
@@ -2813,6 +2925,9 @@ packages:
|
|
2813 | |
2814 |
resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
|
2815 |
|
|
|
|
|
|
|
2816 | |
2817 |
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
2818 |
engines: {node: '>= 8'}
|
@@ -2913,6 +3028,10 @@ packages:
|
|
2913 |
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
2914 |
engines: {node: '>= 0.6'}
|
2915 |
|
|
|
|
|
|
|
|
|
2916 | |
2917 |
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
2918 |
|
@@ -3013,6 +3132,10 @@ packages:
|
|
3013 |
encoding:
|
3014 |
optional: true
|
3015 |
|
|
|
|
|
|
|
|
|
3016 | |
3017 |
resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==}
|
3018 |
|
@@ -3032,6 +3155,10 @@ packages:
|
|
3032 |
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
|
3033 |
engines: {node: '>= 0.4'}
|
3034 |
|
|
|
|
|
|
|
|
|
3035 | |
3036 |
resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==}
|
3037 |
engines: {node: '>= 0.4'}
|
@@ -3059,6 +3186,16 @@ packages:
|
|
3059 |
resolution: {integrity: sha512-y0W+X7Ppo7oZX6eovsRkuzcSM40Bicg2JEJkDJ4irIt1wsYAP5MLSNv+QAogO8xivMffw/9OvV3um1pxXgt1uA==}
|
3060 |
engines: {node: ^10.13.0 || >=12.0.0}
|
3061 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3062 | |
3063 |
resolution: {integrity: sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==}
|
3064 |
|
@@ -3152,6 +3289,9 @@ packages:
|
|
3152 |
resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
|
3153 |
engines: {node: '>=12'}
|
3154 |
|
|
|
|
|
|
|
3155 | |
3156 |
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
3157 |
engines: {node: '>= 0.4'}
|
@@ -3220,6 +3360,9 @@ packages:
|
|
3220 | |
3221 |
resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==}
|
3222 |
|
|
|
|
|
|
|
3223 | |
3224 |
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
3225 |
engines: {node: '>=6'}
|
@@ -3388,6 +3531,9 @@ packages:
|
|
3388 |
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
|
3389 |
engines: {node: '>= 0.4'}
|
3390 |
|
|
|
|
|
|
|
3391 | |
3392 |
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
3393 |
|
@@ -3452,6 +3598,10 @@ packages:
|
|
3452 |
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
|
3453 |
engines: {node: '>=4'}
|
3454 |
|
|
|
|
|
|
|
|
|
3455 | |
3456 |
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
3457 |
engines: {node: '>=8'}
|
@@ -3620,6 +3770,10 @@ packages:
|
|
3620 |
peerDependencies:
|
3621 |
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
3622 |
|
|
|
|
|
|
|
|
|
3623 | |
3624 |
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
3625 |
hasBin: true
|
@@ -3661,6 +3815,11 @@ packages:
|
|
3661 |
engines: {node: '>= 8'}
|
3662 |
hasBin: true
|
3663 |
|
|
|
|
|
|
|
|
|
|
|
3664 | |
3665 |
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
3666 |
engines: {node: '>=0.10.0'}
|
@@ -3689,43 +3848,44 @@ packages:
|
|
3689 |
|
3690 |
snapshots:
|
3691 |
|
3692 |
-
'@ai-sdk/[email protected].
|
3693 |
dependencies:
|
3694 |
'@ai-sdk/provider': 1.1.3
|
3695 |
-
'@ai-sdk/provider-utils': 2.2.
|
3696 |
zod: 3.24.2
|
3697 |
|
3698 |
-
'@ai-sdk/
|
3699 |
dependencies:
|
3700 |
'@ai-sdk/provider': 1.1.3
|
3701 |
-
'@ai-sdk/provider-utils': 2.2.
|
3702 |
zod: 3.24.2
|
3703 |
|
3704 |
-
'@ai-sdk/
|
3705 |
dependencies:
|
3706 |
'@ai-sdk/provider': 1.1.3
|
3707 |
-
'@ai-sdk/provider-utils': 2.2.
|
3708 |
zod: 3.24.2
|
3709 |
|
3710 |
-
'@ai-sdk/
|
3711 |
dependencies:
|
3712 |
'@ai-sdk/provider': 1.1.3
|
3713 |
-
'@ai-sdk/provider-utils': 2.2.
|
3714 |
zod: 3.24.2
|
3715 |
|
3716 |
-
'@ai-sdk/openai
|
3717 |
dependencies:
|
3718 |
'@ai-sdk/provider': 1.1.3
|
3719 |
-
'@ai-sdk/provider-utils': 2.2.
|
3720 |
zod: 3.24.2
|
3721 |
|
3722 |
-
'@ai-sdk/
|
3723 |
dependencies:
|
3724 |
'@ai-sdk/provider': 1.1.3
|
3725 |
-
|
|
|
3726 |
zod: 3.24.2
|
3727 |
|
3728 |
-
'@ai-sdk/[email protected].
|
3729 |
dependencies:
|
3730 |
'@ai-sdk/provider': 1.1.3
|
3731 |
nanoid: 3.3.11
|
@@ -3736,6 +3896,16 @@ snapshots:
|
|
3736 |
dependencies:
|
3737 |
json-schema: 0.4.0
|
3738 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3739 |
'@ai-sdk/[email protected]([email protected])([email protected])':
|
3740 |
dependencies:
|
3741 |
'@ai-sdk/provider-utils': 2.2.7([email protected])
|
@@ -3746,6 +3916,13 @@ snapshots:
|
|
3746 |
optionalDependencies:
|
3747 |
zod: 3.24.2
|
3748 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3749 |
'@ai-sdk/[email protected]([email protected])':
|
3750 |
dependencies:
|
3751 |
'@ai-sdk/provider': 1.1.3
|
@@ -3753,11 +3930,11 @@ snapshots:
|
|
3753 |
zod: 3.24.2
|
3754 |
zod-to-json-schema: 3.24.5([email protected])
|
3755 |
|
3756 |
-
'@ai-sdk/[email protected].
|
3757 |
dependencies:
|
3758 |
-
'@ai-sdk/openai-compatible': 0.2.
|
3759 |
'@ai-sdk/provider': 1.1.3
|
3760 |
-
'@ai-sdk/provider-utils': 2.2.
|
3761 |
zod: 3.24.2
|
3762 |
|
3763 |
'@alloc/[email protected]': {}
|
@@ -3766,11 +3943,57 @@ snapshots:
|
|
3766 |
dependencies:
|
3767 |
regenerator-runtime: 0.14.1
|
3768 |
|
|
|
|
|
3769 |
'@cloudflare/[email protected]':
|
3770 |
optional: true
|
3771 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3772 |
'@drizzle-team/[email protected]': {}
|
3773 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3774 |
'@emnapi/[email protected]':
|
3775 |
dependencies:
|
3776 |
'@emnapi/wasi-threads': 1.0.2
|
@@ -4136,6 +4359,14 @@ snapshots:
|
|
4136 |
'@next/[email protected]':
|
4137 |
optional: true
|
4138 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4139 |
'@nodelib/[email protected]':
|
4140 |
dependencies:
|
4141 |
'@nodelib/fs.stat': 2.0.5
|
@@ -5133,6 +5364,14 @@ snapshots:
|
|
5133 |
|
5134 | |
5135 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5136 | |
5137 |
|
5138 | |
@@ -5228,6 +5467,10 @@ snapshots:
|
|
5228 |
|
5229 | |
5230 |
|
|
|
|
|
|
|
|
|
5231 | |
5232 |
|
5233 | |
@@ -5329,6 +5572,22 @@ snapshots:
|
|
5329 |
es-errors: 1.3.0
|
5330 |
gopd: 1.2.0
|
5331 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5332 | |
5333 |
|
5334 | |
@@ -5699,6 +5958,18 @@ snapshots:
|
|
5699 |
|
5700 | |
5701 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5702 | |
5703 |
|
5704 | |
@@ -5751,6 +6022,8 @@ snapshots:
|
|
5751 |
|
5752 | |
5753 |
|
|
|
|
|
5754 | |
5755 |
dependencies:
|
5756 |
is-callable: 1.2.7
|
@@ -5811,6 +6084,8 @@ snapshots:
|
|
5811 |
dunder-proto: 1.0.1
|
5812 |
es-object-atoms: 1.1.1
|
5813 |
|
|
|
|
|
5814 | |
5815 |
dependencies:
|
5816 |
call-bound: 1.0.4
|
@@ -5902,6 +6177,8 @@ snapshots:
|
|
5902 |
|
5903 | |
5904 |
|
|
|
|
|
5905 | |
5906 |
dependencies:
|
5907 |
ms: 2.1.3
|
@@ -6022,6 +6299,8 @@ snapshots:
|
|
6022 |
dependencies:
|
6023 |
call-bound: 1.0.4
|
6024 |
|
|
|
|
|
6025 | |
6026 |
dependencies:
|
6027 |
call-bound: 1.0.4
|
@@ -6052,6 +6331,8 @@ snapshots:
|
|
6052 |
|
6053 | |
6054 |
|
|
|
|
|
6055 | |
6056 |
dependencies:
|
6057 |
define-data-property: 1.1.4
|
@@ -6333,6 +6614,8 @@ snapshots:
|
|
6333 |
dependencies:
|
6334 |
'@types/mdast': 4.0.4
|
6335 |
|
|
|
|
|
6336 | |
6337 |
|
6338 | |
@@ -6537,6 +6820,8 @@ snapshots:
|
|
6537 |
dependencies:
|
6538 |
mime-db: 1.52.0
|
6539 |
|
|
|
|
|
6540 | |
6541 |
dependencies:
|
6542 |
brace-expansion: 1.1.11
|
@@ -6621,6 +6906,10 @@ snapshots:
|
|
6621 |
dependencies:
|
6622 |
whatwg-url: 5.0.0
|
6623 |
|
|
|
|
|
|
|
|
|
6624 | |
6625 |
|
6626 | |
@@ -6631,6 +6920,8 @@ snapshots:
|
|
6631 |
|
6632 | |
6633 |
|
|
|
|
|
6634 | |
6635 |
dependencies:
|
6636 |
call-bind: 1.0.8
|
@@ -6671,6 +6962,16 @@ snapshots:
|
|
6671 |
|
6672 | |
6673 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6674 | |
6675 |
dependencies:
|
6676 |
jose: 4.15.9
|
@@ -6776,6 +7077,8 @@ snapshots:
|
|
6776 |
|
6777 | |
6778 |
|
|
|
|
|
6779 | |
6780 |
|
6781 | |
@@ -6831,6 +7134,8 @@ snapshots:
|
|
6831 |
|
6832 | |
6833 |
|
|
|
|
|
6834 | |
6835 |
|
6836 | |
@@ -7078,6 +7383,8 @@ snapshots:
|
|
7078 |
side-channel-map: 1.0.1
|
7079 |
side-channel-weakmap: 1.0.2
|
7080 |
|
|
|
|
|
7081 | |
7082 |
dependencies:
|
7083 |
is-arrayish: 0.3.2
|
@@ -7162,6 +7469,8 @@ snapshots:
|
|
7162 |
|
7163 | |
7164 |
|
|
|
|
|
7165 | |
7166 |
|
7167 | |
@@ -7354,6 +7663,8 @@ snapshots:
|
|
7354 |
dependencies:
|
7355 |
react: 19.1.0
|
7356 |
|
|
|
|
|
7357 | |
7358 |
|
7359 | |
@@ -7420,6 +7731,10 @@ snapshots:
|
|
7420 |
dependencies:
|
7421 |
isexe: 2.0.0
|
7422 |
|
|
|
|
|
|
|
|
|
7423 | |
7424 |
|
7425 |
|
|
9 |
.:
|
10 |
dependencies:
|
11 |
'@ai-sdk/anthropic':
|
12 |
+
specifier: ^1.2.11
|
13 |
+
version: 1.2.11([email protected])
|
|
|
|
|
|
|
14 |
'@ai-sdk/google':
|
15 |
+
specifier: ^1.2.17
|
16 |
+
version: 1.2.17([email protected])
|
17 |
'@ai-sdk/groq':
|
18 |
+
specifier: ^1.2.9
|
19 |
+
version: 1.2.9([email protected])
|
20 |
'@ai-sdk/openai':
|
21 |
+
specifier: ^1.3.22
|
22 |
+
version: 1.3.22([email protected])
|
23 |
'@ai-sdk/react':
|
24 |
+
specifier: ^1.2.12
|
25 |
+
version: 1.2.12([email protected])([email protected])
|
26 |
'@ai-sdk/xai':
|
27 |
+
specifier: ^1.2.16
|
28 |
+
version: 1.2.16([email protected])
|
29 |
+
'@daytonaio/sdk':
|
30 |
+
specifier: ^0.17.0
|
31 |
+
version: 0.17.0
|
32 |
+
'@e2b/code-interpreter':
|
33 |
+
specifier: ^1.5.0
|
34 |
+
version: 1.5.0
|
35 |
'@neondatabase/serverless':
|
36 |
specifier: ^1.0.0
|
37 |
version: 1.0.0
|
|
|
189 |
|
190 |
packages:
|
191 |
|
192 |
+
'@ai-sdk/[email protected].11':
|
193 |
+
resolution: {integrity: sha512-lZLcEMh8MXY4NVSrN/7DyI2rnid8k7cn/30nMmd3bwJrnIsOuIuuFvY8f0nj+pFcTi6AYK7ujLdqW5dQVz1YQw==}
|
194 |
engines: {node: '>=18'}
|
195 |
peerDependencies:
|
196 |
zod: ^3.0.0
|
197 |
|
198 |
+
'@ai-sdk/google@1.2.17':
|
199 |
+
resolution: {integrity: sha512-mLFLDMCJaDK+j1nvoqeNszazSZIyeSMPi5X+fs5Wh3xWZljGGE0WmFg32RNkFujRB+UnM63EnhPG70WdqOx/MA==}
|
200 |
engines: {node: '>=18'}
|
201 |
peerDependencies:
|
202 |
zod: ^3.0.0
|
203 |
|
204 |
+
'@ai-sdk/groq@1.2.9':
|
205 |
+
resolution: {integrity: sha512-7MoDaxm8yWtiRbD1LipYZG0kBl+Xe0sv/EeyxnHnGPZappXdlgtdOgTZVjjXkT3nWP30jjZi9A45zoVrBMb3Xg==}
|
206 |
engines: {node: '>=18'}
|
207 |
peerDependencies:
|
208 |
zod: ^3.0.0
|
209 |
|
210 |
+
'@ai-sdk/openai-compatible@0.2.14':
|
211 |
+
resolution: {integrity: sha512-icjObfMCHKSIbywijaoLdZ1nSnuRnWgMEMLgwoxPJgxsUHMx0aVORnsLUid4SPtdhHI3X2masrt6iaEQLvOSFw==}
|
212 |
engines: {node: '>=18'}
|
213 |
peerDependencies:
|
214 |
zod: ^3.0.0
|
215 |
|
216 |
+
'@ai-sdk/openai@1.3.22':
|
217 |
+
resolution: {integrity: sha512-QwA+2EkG0QyjVR+7h6FE7iOu2ivNqAVMm9UJZkVxxTk5OIq5fFJDTEI/zICEMuHImTTXR2JjsL6EirJ28Jc4cw==}
|
218 |
engines: {node: '>=18'}
|
219 |
peerDependencies:
|
220 |
zod: ^3.0.0
|
221 |
|
222 |
+
'@ai-sdk/provider-utils@2.2.7':
|
223 |
+
resolution: {integrity: sha512-kM0xS3GWg3aMChh9zfeM+80vEZfXzR3JEUBdycZLtbRZ2TRT8xOj3WodGHPb06sUK5yD7pAXC/P7ctsi2fvUGQ==}
|
224 |
engines: {node: '>=18'}
|
225 |
peerDependencies:
|
226 |
+
zod: ^3.23.8
|
227 |
|
228 |
+
'@ai-sdk/[email protected].8':
|
229 |
+
resolution: {integrity: sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA==}
|
230 |
engines: {node: '>=18'}
|
231 |
peerDependencies:
|
232 |
zod: ^3.23.8
|
|
|
235 |
resolution: {integrity: sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg==}
|
236 |
engines: {node: '>=18'}
|
237 |
|
238 |
+
'@ai-sdk/[email protected]':
|
239 |
+
resolution: {integrity: sha512-jK1IZZ22evPZoQW3vlkZ7wvjYGYF+tRBKXtrcolduIkQ/m/sOAVcVeVDUDvh1T91xCnWCdUGCPZg2avZ90mv3g==}
|
240 |
+
engines: {node: '>=18'}
|
241 |
+
peerDependencies:
|
242 |
+
react: ^18 || ^19 || ^19.0.0-rc
|
243 |
+
zod: ^3.23.8
|
244 |
+
peerDependenciesMeta:
|
245 |
+
zod:
|
246 |
+
optional: true
|
247 |
+
|
248 |
'@ai-sdk/[email protected]':
|
249 |
resolution: {integrity: sha512-/VYm8xifyngaqFDLXACk/1czDRCefNCdALUyp+kIX6DUIYUWTM93ISoZ+qJ8+3E+FiJAKBQz61o8lIIl+vYtzg==}
|
250 |
engines: {node: '>=18'}
|
|
|
255 |
zod:
|
256 |
optional: true
|
257 |
|
258 |
+
'@ai-sdk/[email protected]':
|
259 |
+
resolution: {integrity: sha512-3zcwCc8ezzFlwp3ZD15wAPjf2Au4s3vAbKsXQVyhxODHcmu0iyPO2Eua6D/vicq/AUm/BAo60r97O6HU+EI0+w==}
|
260 |
+
engines: {node: '>=18'}
|
261 |
+
peerDependencies:
|
262 |
+
zod: ^3.23.8
|
263 |
+
|
264 |
'@ai-sdk/[email protected]':
|
265 |
resolution: {integrity: sha512-nls/IJCY+ks3Uj6G/agNhXqQeLVqhNfoJbuNgCny+nX2veY5ADB91EcZUqVeQ/ionul2SeUswPY6Q/DxteY29Q==}
|
266 |
engines: {node: '>=18'}
|
267 |
peerDependencies:
|
268 |
zod: ^3.23.8
|
269 |
|
270 |
+
'@ai-sdk/[email protected].16':
|
271 |
+
resolution: {integrity: sha512-UOZT8td9PWwMi2dF9a0U44t/Oltmf6QmIJdSvrOcLG4mvpRc1UJn6YJaR0HtXs3YnW6SvY1zRdIDrW4GFpv4NA==}
|
272 |
engines: {node: '>=18'}
|
273 |
peerDependencies:
|
274 |
zod: ^3.0.0
|
|
|
281 |
resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==}
|
282 |
engines: {node: '>=6.9.0'}
|
283 |
|
284 |
+
'@bufbuild/[email protected]':
|
285 |
+
resolution: {integrity: sha512-WK6zH4MtBp/uesX8KGCnwDDRVnEVHUvwjsigKXcSR57Oo8Oyv1vRS9qyUlSP+6KWRl5z8tNAU5qpf3QodeVYxA==}
|
286 |
+
|
287 |
'@cloudflare/[email protected]':
|
288 |
resolution: {integrity: sha512-uu8gZ8P6teFsyfJOIXBrNC4ZsjLWPUEMeDqbQCdJ8OA6Rs/8QoUYD7ZSLW2kxsO/6upcbZir1WGrWp8088aVWg==}
|
289 |
|
290 |
+
'@connectrpc/[email protected]':
|
291 |
+
resolution: {integrity: sha512-w88P8Lsn5CCsA7MFRl2e6oLY4J/5toiNtJns/YJrlyQaWOy3RO8pDgkz+iIkG98RPMhj2thuBvsd3Cn4DKKCkw==}
|
292 |
+
peerDependencies:
|
293 |
+
'@bufbuild/protobuf': ^2.2.0
|
294 |
+
'@connectrpc/connect': 2.0.0-rc.3
|
295 |
+
|
296 |
+
'@connectrpc/[email protected]':
|
297 |
+
resolution: {integrity: sha512-ARBt64yEyKbanyRETTjcjJuHr2YXorzQo0etyS5+P6oSeW8xEuzajA9g+zDnMcj1hlX2dQE93foIWQGfpru7gQ==}
|
298 |
+
peerDependencies:
|
299 |
+
'@bufbuild/protobuf': ^2.2.0
|
300 |
+
|
301 |
+
'@daytonaio/[email protected]':
|
302 |
+
resolution: {integrity: sha512-XvnvZkS/i207CxvVR8LuyUkmsCj0Z202l6SD/G9TnUl15PJsmu3OuOQcUJ/PjS1bhaGzKDvEOlHJGZHMwCDAVg==}
|
303 |
+
|
304 |
+
'@daytonaio/[email protected]':
|
305 |
+
resolution: {integrity: sha512-1tolkjpAsW0Byqvf6C0SYMr6yEM/v4MkEjrcIK3w13J1c2zM9ubRtzNC6/b9zWnLapX19SaWsMIzVLFfOjRmsg==}
|
306 |
+
|
307 |
+
'@dotenvx/[email protected]':
|
308 |
+
resolution: {integrity: sha512-Z8XjM75aWZ/ekUzBjlr/OqQsLWtJY4nVtruxopAt+FlYHfY0/gKl85nD16aEqbTkU53kJcm5psID0L2/sQMmuw==}
|
309 |
+
hasBin: true
|
310 |
+
|
311 |
'@drizzle-team/[email protected]':
|
312 |
resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==}
|
313 |
|
314 |
+
'@e2b/[email protected]':
|
315 |
+
resolution: {integrity: sha512-9uO8Q5Hfhi6f2rSt0lcshLyhNF6pfh+36StE1dO8RrcMwi3F7MNSyWhKm0/KV9AJjviLZ8lSFFlwXi5/iKyLEA==}
|
316 |
+
engines: {node: '>=18'}
|
317 |
+
|
318 |
+
'@ecies/[email protected]':
|
319 |
+
resolution: {integrity: sha512-tapn6XhOueMwht3E2UzY0ZZjYokdaw9XtL9kEyjhQ/Fb9vL9xTFbOaI+fV0AWvTpYu4BNloC6getKW6NtSg4mA==}
|
320 |
+
engines: {bun: '>=1', deno: '>=2', node: '>=16'}
|
321 |
+
peerDependencies:
|
322 |
+
'@noble/ciphers': ^1.0.0
|
323 |
+
|
324 |
'@emnapi/[email protected]':
|
325 |
resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==}
|
326 |
|
|
|
868 |
cpu: [x64]
|
869 |
os: [win32]
|
870 |
|
871 |
+
'@noble/[email protected]':
|
872 |
+
resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==}
|
873 |
+
engines: {node: ^14.21.3 || >=16}
|
874 |
+
|
875 |
+
'@noble/[email protected]':
|
876 |
+
resolution: {integrity: sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==}
|
877 |
+
engines: {node: ^14.21.3 || >=16}
|
878 |
+
|
879 |
+
'@noble/[email protected]':
|
880 |
+
resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
|
881 |
+
engines: {node: ^14.21.3 || >=16}
|
882 |
+
|
883 |
'@nodelib/[email protected]':
|
884 |
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
885 |
engines: {node: '>= 8'}
|
|
|
1892 |
resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==}
|
1893 |
engines: {node: '>=4'}
|
1894 |
|
1895 | |
1896 |
+
resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==}
|
1897 |
+
|
1898 | |
1899 |
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
|
1900 |
engines: {node: '>= 0.4'}
|
|
|
1995 | |
1996 |
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
|
1997 |
|
1998 | |
1999 |
+
resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
|
2000 |
+
engines: {node: '>=16'}
|
2001 |
+
|
2002 | |
2003 |
+
resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==}
|
2004 |
+
|
2005 | |
2006 |
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
2007 |
|
|
|
2188 |
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
2189 |
engines: {node: '>= 0.4'}
|
2190 |
|
2191 | |
2192 |
+
resolution: {integrity: sha512-KGe5F5UI+1PZ82OBjPHsYqpbw33ck7j0xgcJRSS56mAOWMX/Z6xllXqbZj66Xg6kkO32GmSGXjCAZL4FMSfyug==}
|
2193 |
+
engines: {node: '>=18'}
|
2194 |
+
|
2195 | |
2196 |
+
resolution: {integrity: sha512-eJAgf9pdv214Hn98FlUzclRMYWF7WfoLlkS9nWMTm1qcCwn6Ad4EGD9lr9HXMBfSrZhYQujRE+p0adPRkctC6A==}
|
2197 |
+
engines: {bun: '>=1', deno: '>=2', node: '>=16'}
|
2198 |
+
|
2199 | |
2200 |
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
|
2201 |
|
|
|
2381 |
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
2382 |
engines: {node: '>=6'}
|
2383 |
|
2384 | |
2385 |
+
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
|
2386 |
+
engines: {node: '>=10'}
|
2387 |
+
|
2388 | |
2389 |
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
|
2390 |
|
|
|
2435 | |
2436 |
resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
|
2437 |
|
2438 | |
2439 |
+
resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
|
2440 |
+
engines: {node: '>=4.0'}
|
2441 |
+
peerDependencies:
|
2442 |
+
debug: '*'
|
2443 |
+
peerDependenciesMeta:
|
2444 |
+
debug:
|
2445 |
+
optional: true
|
2446 |
+
|
2447 | |
2448 |
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
|
2449 |
engines: {node: '>= 0.4'}
|
|
|
2495 |
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
|
2496 |
engines: {node: '>= 0.4'}
|
2497 |
|
2498 | |
2499 |
+
resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
|
2500 |
+
engines: {node: '>=10'}
|
2501 |
+
|
2502 | |
2503 |
resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
|
2504 |
engines: {node: '>= 0.4'}
|
|
|
2571 | |
2572 |
resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
|
2573 |
|
2574 | |
2575 |
+
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
|
2576 |
+
engines: {node: '>=10.17.0'}
|
2577 |
+
|
2578 | |
2579 |
resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
|
2580 |
|
|
|
2691 |
resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==}
|
2692 |
engines: {node: '>= 0.4'}
|
2693 |
|
2694 | |
2695 |
+
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
|
2696 |
+
engines: {node: '>=8'}
|
2697 |
+
|
2698 | |
2699 |
resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==}
|
2700 |
engines: {node: '>= 0.4'}
|
|
|
2725 | |
2726 |
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
2727 |
|
2728 | |
2729 |
+
resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==}
|
2730 |
+
engines: {node: '>=16'}
|
2731 |
+
|
2732 | |
2733 |
resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
|
2734 |
engines: {node: '>= 0.4'}
|
|
|
2925 | |
2926 |
resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
|
2927 |
|
2928 | |
2929 |
+
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
|
2930 |
+
|
2931 | |
2932 |
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
2933 |
engines: {node: '>= 8'}
|
|
|
3028 |
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
3029 |
engines: {node: '>= 0.6'}
|
3030 |
|
3031 | |
3032 |
+
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
|
3033 |
+
engines: {node: '>=6'}
|
3034 |
+
|
3035 | |
3036 |
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
3037 |
|
|
|
3132 |
encoding:
|
3133 |
optional: true
|
3134 |
|
3135 | |
3136 |
+
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
|
3137 |
+
engines: {node: '>=8'}
|
3138 |
+
|
3139 | |
3140 |
resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==}
|
3141 |
|
|
|
3155 |
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
|
3156 |
engines: {node: '>= 0.4'}
|
3157 |
|
3158 | |
3159 |
+
resolution: {integrity: sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==}
|
3160 |
+
engines: {node: '>= 10'}
|
3161 |
+
|
3162 | |
3163 |
resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==}
|
3164 |
engines: {node: '>= 0.4'}
|
|
|
3186 |
resolution: {integrity: sha512-y0W+X7Ppo7oZX6eovsRkuzcSM40Bicg2JEJkDJ4irIt1wsYAP5MLSNv+QAogO8xivMffw/9OvV3um1pxXgt1uA==}
|
3187 |
engines: {node: ^10.13.0 || >=12.0.0}
|
3188 |
|
3189 | |
3190 |
+
resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
|
3191 |
+
engines: {node: '>=6'}
|
3192 |
+
|
3193 | |
3194 |
+
resolution: {integrity: sha512-zM6elH0EZStD/gSiNlcPrzXcVQ/pZo3BDvC6CDwRDUt1dDzxlshpmQnpD6cZaJ39THaSmwVCxxRrPKNM1hHrDg==}
|
3195 |
+
|
3196 | |
3197 |
+
resolution: {integrity: sha512-1eNjQtbfNi5Z/kFhagDIaIRj6qqDzhjNJKz8cmMW0CVdGwT6e1GLbAfgI0d28VTJa1A8jz82jm/4dG8qNoNS8g==}
|
3198 |
+
|
3199 | |
3200 |
resolution: {integrity: sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==}
|
3201 |
|
|
|
3289 |
resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
|
3290 |
engines: {node: '>=12'}
|
3291 |
|
3292 | |
3293 |
+
resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==}
|
3294 |
+
|
3295 | |
3296 |
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
3297 |
engines: {node: '>= 0.4'}
|
|
|
3360 | |
3361 |
resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==}
|
3362 |
|
3363 | |
3364 |
+
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
3365 |
+
|
3366 | |
3367 |
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
3368 |
engines: {node: '>=6'}
|
|
|
3531 |
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
|
3532 |
engines: {node: '>= 0.4'}
|
3533 |
|
3534 | |
3535 |
+
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
3536 |
+
|
3537 | |
3538 |
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
3539 |
|
|
|
3598 |
resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
|
3599 |
engines: {node: '>=4'}
|
3600 |
|
3601 | |
3602 |
+
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
|
3603 |
+
engines: {node: '>=6'}
|
3604 |
+
|
3605 | |
3606 |
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
3607 |
engines: {node: '>=8'}
|
|
|
3770 |
peerDependencies:
|
3771 |
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
3772 |
|
3773 | |
3774 |
+
resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==}
|
3775 |
+
hasBin: true
|
3776 |
+
|
3777 | |
3778 |
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
3779 |
hasBin: true
|
|
|
3815 |
engines: {node: '>= 8'}
|
3816 |
hasBin: true
|
3817 |
|
3818 | |
3819 |
+
resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==}
|
3820 |
+
engines: {node: ^16.13.0 || >=18.0.0}
|
3821 |
+
hasBin: true
|
3822 |
+
|
3823 | |
3824 |
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
3825 |
engines: {node: '>=0.10.0'}
|
|
|
3848 |
|
3849 |
snapshots:
|
3850 |
|
3851 |
+
'@ai-sdk/[email protected].11([email protected])':
|
3852 |
dependencies:
|
3853 |
'@ai-sdk/provider': 1.1.3
|
3854 |
+
'@ai-sdk/provider-utils': 2.2.8([email protected])
|
3855 |
zod: 3.24.2
|
3856 |
|
3857 |
+
'@ai-sdk/google@1.2.17([email protected])':
|
3858 |
dependencies:
|
3859 |
'@ai-sdk/provider': 1.1.3
|
3860 |
+
'@ai-sdk/provider-utils': 2.2.8([email protected])
|
3861 |
zod: 3.24.2
|
3862 |
|
3863 |
+
'@ai-sdk/groq@1.2.9([email protected])':
|
3864 |
dependencies:
|
3865 |
'@ai-sdk/provider': 1.1.3
|
3866 |
+
'@ai-sdk/provider-utils': 2.2.8([email protected])
|
3867 |
zod: 3.24.2
|
3868 |
|
3869 |
+
'@ai-sdk/openai-compatible@0.2.14([email protected])':
|
3870 |
dependencies:
|
3871 |
'@ai-sdk/provider': 1.1.3
|
3872 |
+
'@ai-sdk/provider-utils': 2.2.8([email protected])
|
3873 |
zod: 3.24.2
|
3874 |
|
3875 |
+
'@ai-sdk/openai@1.3.22([email protected])':
|
3876 |
dependencies:
|
3877 |
'@ai-sdk/provider': 1.1.3
|
3878 |
+
'@ai-sdk/provider-utils': 2.2.8([email protected])
|
3879 |
zod: 3.24.2
|
3880 |
|
3881 |
+
'@ai-sdk/provider-utils@2.2.7([email protected])':
|
3882 |
dependencies:
|
3883 |
'@ai-sdk/provider': 1.1.3
|
3884 |
+
nanoid: 3.3.11
|
3885 |
+
secure-json-parse: 2.7.0
|
3886 |
zod: 3.24.2
|
3887 |
|
3888 |
+
'@ai-sdk/[email protected].8([email protected])':
|
3889 |
dependencies:
|
3890 |
'@ai-sdk/provider': 1.1.3
|
3891 |
nanoid: 3.3.11
|
|
|
3896 |
dependencies:
|
3897 |
json-schema: 0.4.0
|
3898 |
|
3899 |
+
'@ai-sdk/[email protected]([email protected])([email protected])':
|
3900 |
+
dependencies:
|
3901 |
+
'@ai-sdk/provider-utils': 2.2.8([email protected])
|
3902 |
+
'@ai-sdk/ui-utils': 1.2.11([email protected])
|
3903 |
+
react: 19.1.0
|
3904 |
+
swr: 2.3.3([email protected])
|
3905 |
+
throttleit: 2.1.0
|
3906 |
+
optionalDependencies:
|
3907 |
+
zod: 3.24.2
|
3908 |
+
|
3909 |
'@ai-sdk/[email protected]([email protected])([email protected])':
|
3910 |
dependencies:
|
3911 |
'@ai-sdk/provider-utils': 2.2.7([email protected])
|
|
|
3916 |
optionalDependencies:
|
3917 |
zod: 3.24.2
|
3918 |
|
3919 |
+
'@ai-sdk/[email protected]([email protected])':
|
3920 |
+
dependencies:
|
3921 |
+
'@ai-sdk/provider': 1.1.3
|
3922 |
+
'@ai-sdk/provider-utils': 2.2.8([email protected])
|
3923 |
+
zod: 3.24.2
|
3924 |
+
zod-to-json-schema: 3.24.5([email protected])
|
3925 |
+
|
3926 |
'@ai-sdk/[email protected]([email protected])':
|
3927 |
dependencies:
|
3928 |
'@ai-sdk/provider': 1.1.3
|
|
|
3930 |
zod: 3.24.2
|
3931 |
zod-to-json-schema: 3.24.5([email protected])
|
3932 |
|
3933 |
+
'@ai-sdk/[email protected].16([email protected])':
|
3934 |
dependencies:
|
3935 |
+
'@ai-sdk/openai-compatible': 0.2.14([email protected])
|
3936 |
'@ai-sdk/provider': 1.1.3
|
3937 |
+
'@ai-sdk/provider-utils': 2.2.8([email protected])
|
3938 |
zod: 3.24.2
|
3939 |
|
3940 |
'@alloc/[email protected]': {}
|
|
|
3943 |
dependencies:
|
3944 |
regenerator-runtime: 0.14.1
|
3945 |
|
3946 |
+
'@bufbuild/[email protected]': {}
|
3947 |
+
|
3948 |
'@cloudflare/[email protected]':
|
3949 |
optional: true
|
3950 |
|
3951 |
+
'@connectrpc/[email protected](@bufbuild/[email protected])(@connectrpc/[email protected](@bufbuild/[email protected]))':
|
3952 |
+
dependencies:
|
3953 |
+
'@bufbuild/protobuf': 2.3.0
|
3954 |
+
'@connectrpc/connect': 2.0.0-rc.3(@bufbuild/[email protected])
|
3955 |
+
|
3956 |
+
'@connectrpc/[email protected](@bufbuild/[email protected])':
|
3957 |
+
dependencies:
|
3958 |
+
'@bufbuild/protobuf': 2.3.0
|
3959 |
+
|
3960 |
+
'@daytonaio/[email protected]':
|
3961 |
+
dependencies:
|
3962 |
+
axios: 1.9.0
|
3963 |
+
transitivePeerDependencies:
|
3964 |
+
- debug
|
3965 |
+
|
3966 |
+
'@daytonaio/[email protected]':
|
3967 |
+
dependencies:
|
3968 |
+
'@daytonaio/api-client': 0.18.1
|
3969 |
+
'@dotenvx/dotenvx': 1.43.0
|
3970 |
+
axios: 1.9.0
|
3971 |
+
uuid: 11.1.0
|
3972 |
+
transitivePeerDependencies:
|
3973 |
+
- debug
|
3974 |
+
|
3975 |
+
'@dotenvx/[email protected]':
|
3976 |
+
dependencies:
|
3977 |
+
commander: 11.1.0
|
3978 |
+
dotenv: 16.5.0
|
3979 |
+
eciesjs: 0.4.14
|
3980 |
+
execa: 5.1.1
|
3981 |
+
fdir: 6.4.3([email protected])
|
3982 |
+
ignore: 5.3.2
|
3983 |
+
object-treeify: 1.1.33
|
3984 |
+
picomatch: 4.0.2
|
3985 |
+
which: 4.0.0
|
3986 |
+
|
3987 |
'@drizzle-team/[email protected]': {}
|
3988 |
|
3989 |
+
'@e2b/[email protected]':
|
3990 |
+
dependencies:
|
3991 |
+
e2b: 1.4.0
|
3992 |
+
|
3993 |
+
'@ecies/[email protected](@noble/[email protected])':
|
3994 |
+
dependencies:
|
3995 |
+
'@noble/ciphers': 1.3.0
|
3996 |
+
|
3997 |
'@emnapi/[email protected]':
|
3998 |
dependencies:
|
3999 |
'@emnapi/wasi-threads': 1.0.2
|
|
|
4359 |
'@next/[email protected]':
|
4360 |
optional: true
|
4361 |
|
4362 |
+
'@noble/[email protected]': {}
|
4363 |
+
|
4364 |
+
'@noble/[email protected]':
|
4365 |
+
dependencies:
|
4366 |
+
'@noble/hashes': 1.8.0
|
4367 |
+
|
4368 |
+
'@noble/[email protected]': {}
|
4369 |
+
|
4370 |
'@nodelib/[email protected]':
|
4371 |
dependencies:
|
4372 |
'@nodelib/fs.stat': 2.0.5
|
|
|
5364 |
|
5365 | |
5366 |
|
5367 | |
5368 |
+
dependencies:
|
5369 |
+
follow-redirects: 1.15.9
|
5370 |
+
form-data: 4.0.2
|
5371 |
+
proxy-from-env: 1.1.0
|
5372 |
+
transitivePeerDependencies:
|
5373 |
+
- debug
|
5374 |
+
|
5375 | |
5376 |
|
5377 | |
|
|
5467 |
|
5468 | |
5469 |
|
5470 |
+
[email protected]: {}
|
5471 |
+
|
5472 |
+
[email protected]: {}
|
5473 |
+
|
5474 | |
5475 |
|
5476 | |
|
|
5572 |
es-errors: 1.3.0
|
5573 |
gopd: 1.2.0
|
5574 |
|
5575 | |
5576 |
+
dependencies:
|
5577 |
+
'@bufbuild/protobuf': 2.3.0
|
5578 |
+
'@connectrpc/connect': 2.0.0-rc.3(@bufbuild/[email protected])
|
5579 |
+
'@connectrpc/connect-web': 2.0.0-rc.3(@bufbuild/[email protected])(@connectrpc/[email protected](@bufbuild/[email protected]))
|
5580 |
+
compare-versions: 6.1.1
|
5581 |
+
openapi-fetch: 0.9.8
|
5582 |
+
platform: 1.3.6
|
5583 |
+
|
5584 | |
5585 |
+
dependencies:
|
5586 |
+
'@ecies/ciphers': 0.2.3(@noble/[email protected])
|
5587 |
+
'@noble/ciphers': 1.3.0
|
5588 |
+
'@noble/curves': 1.9.0
|
5589 |
+
'@noble/hashes': 1.8.0
|
5590 |
+
|
5591 | |
5592 |
|
5593 | |
|
|
5958 |
|
5959 | |
5960 |
|
5961 | |
5962 |
+
dependencies:
|
5963 |
+
cross-spawn: 7.0.6
|
5964 |
+
get-stream: 6.0.1
|
5965 |
+
human-signals: 2.1.0
|
5966 |
+
is-stream: 2.0.1
|
5967 |
+
merge-stream: 2.0.0
|
5968 |
+
npm-run-path: 4.0.1
|
5969 |
+
onetime: 5.1.2
|
5970 |
+
signal-exit: 3.0.7
|
5971 |
+
strip-final-newline: 2.0.0
|
5972 |
+
|
5973 | |
5974 |
|
5975 | |
|
|
6022 |
|
6023 | |
6024 |
|
6025 |
+
[email protected]: {}
|
6026 |
+
|
6027 | |
6028 |
dependencies:
|
6029 |
is-callable: 1.2.7
|
|
|
6084 |
dunder-proto: 1.0.1
|
6085 |
es-object-atoms: 1.1.1
|
6086 |
|
6087 |
+
[email protected]: {}
|
6088 |
+
|
6089 | |
6090 |
dependencies:
|
6091 |
call-bound: 1.0.4
|
|
|
6177 |
|
6178 | |
6179 |
|
6180 |
+
[email protected]: {}
|
6181 |
+
|
6182 | |
6183 |
dependencies:
|
6184 |
ms: 2.1.3
|
|
|
6299 |
dependencies:
|
6300 |
call-bound: 1.0.4
|
6301 |
|
6302 |
+
[email protected]: {}
|
6303 |
+
|
6304 | |
6305 |
dependencies:
|
6306 |
call-bound: 1.0.4
|
|
|
6331 |
|
6332 | |
6333 |
|
6334 |
+
[email protected]: {}
|
6335 |
+
|
6336 | |
6337 |
dependencies:
|
6338 |
define-data-property: 1.1.4
|
|
|
6614 |
dependencies:
|
6615 |
'@types/mdast': 4.0.4
|
6616 |
|
6617 |
+
[email protected]: {}
|
6618 |
+
|
6619 | |
6620 |
|
6621 | |
|
|
6820 |
dependencies:
|
6821 |
mime-db: 1.52.0
|
6822 |
|
6823 |
+
[email protected]: {}
|
6824 |
+
|
6825 | |
6826 |
dependencies:
|
6827 |
brace-expansion: 1.1.11
|
|
|
6906 |
dependencies:
|
6907 |
whatwg-url: 5.0.0
|
6908 |
|
6909 | |
6910 |
+
dependencies:
|
6911 |
+
path-key: 3.1.1
|
6912 |
+
|
6913 | |
6914 |
|
6915 | |
|
|
6920 |
|
6921 | |
6922 |
|
6923 |
+
[email protected]: {}
|
6924 |
+
|
6925 | |
6926 |
dependencies:
|
6927 |
call-bind: 1.0.8
|
|
|
6962 |
|
6963 | |
6964 |
|
6965 | |
6966 |
+
dependencies:
|
6967 |
+
mimic-fn: 2.1.0
|
6968 |
+
|
6969 | |
6970 |
+
dependencies:
|
6971 |
+
openapi-typescript-helpers: 0.0.8
|
6972 |
+
|
6973 |
+
[email protected]: {}
|
6974 |
+
|
6975 | |
6976 |
dependencies:
|
6977 |
jose: 4.15.9
|
|
|
7077 |
|
7078 | |
7079 |
|
7080 |
+
[email protected]: {}
|
7081 |
+
|
7082 | |
7083 |
|
7084 | |
|
|
7134 |
|
7135 | |
7136 |
|
7137 |
+
[email protected]: {}
|
7138 |
+
|
7139 | |
7140 |
|
7141 | |
|
|
7383 |
side-channel-map: 1.0.1
|
7384 |
side-channel-weakmap: 1.0.2
|
7385 |
|
7386 |
+
[email protected]: {}
|
7387 |
+
|
7388 | |
7389 |
dependencies:
|
7390 |
is-arrayish: 0.3.2
|
|
|
7469 |
|
7470 | |
7471 |
|
7472 |
+
[email protected]: {}
|
7473 |
+
|
7474 | |
7475 |
|
7476 | |
|
|
7663 |
dependencies:
|
7664 |
react: 19.1.0
|
7665 |
|
7666 |
+
[email protected]: {}
|
7667 |
+
|
7668 | |
7669 |
|
7670 | |
|
|
7731 |
dependencies:
|
7732 |
isexe: 2.0.0
|
7733 |
|
7734 | |
7735 |
+
dependencies:
|
7736 |
+
isexe: 3.1.1
|
7737 |
+
|
7738 | |
7739 |
|
7740 |