Buckets:
| import type { ToolResult } from '../../types/tool-result.js'; | |
| import type { InvokeResult } from '../types.js'; | |
| import type { Tool, ServerNotification, ServerRequest } from '@modelcontextprotocol/sdk/types.js'; | |
| import type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js'; | |
| import { analyzeSchemaComplexity, validateParameters, applyDefaults } from '../utils/schema-validator.js'; | |
| import { formatComplexSchemaError, formatValidationError } from '../utils/parameter-formatter.js'; | |
| import { callGradioToolWithHeaders } from '../utils/gradio-caller.js'; | |
| import { fetchGradioSchema, fetchSpaceMetadata } from '../utils/space-http.js'; | |
| /** | |
| * Invokes a Gradio space with provided parameters | |
| * Returns raw MCP content blocks for compatibility with proxied gr_* tools | |
| */ | |
| export async function invokeSpace( | |
| spaceName: string, | |
| parametersJson: string, | |
| hfToken?: string, | |
| extra?: RequestHandlerExtra<ServerRequest, ServerNotification> | |
| ): Promise<InvokeResult | ToolResult> { | |
| try { | |
| // Step 1: Parse parameters JSON | |
| let inputParameters: Record<string, unknown>; | |
| try { | |
| const parsed: unknown = JSON.parse(parametersJson); | |
| if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) { | |
| throw new Error('Parameters must be a JSON object'); | |
| } | |
| inputParameters = parsed as Record<string, unknown>; | |
| } catch (error) { | |
| return { | |
| formatted: `Error: Invalid JSON in parameters.\n\nExpected format: {"param1": "value", "param2": 123}\nNote: Use double quotes, no trailing commas.\n\n${error instanceof Error ? error.message : String(error)}`, | |
| totalResults: 0, | |
| resultsShared: 0, | |
| isError: true, | |
| }; | |
| } | |
| // Step 2: Fetch space metadata to get subdomain | |
| const metadata = await fetchSpaceMetadata(spaceName, hfToken); | |
| // Step 3: Fetch schema from Gradio endpoint | |
| const tools = await fetchGradioSchema(metadata.subdomain, metadata.private, hfToken); | |
| if (tools.length === 0) { | |
| return { | |
| formatted: `Error: No tools found for space '${spaceName}'.`, | |
| totalResults: 0, | |
| resultsShared: 0, | |
| isError: true, | |
| }; | |
| } | |
| const tool = tools[0] as Tool; | |
| // Step 4: Analyze schema complexity | |
| const schemaResult = analyzeSchemaComplexity(tool); | |
| if (!schemaResult.isSimple) { | |
| return { | |
| formatted: formatComplexSchemaError(spaceName, schemaResult.reason || 'Unknown reason'), | |
| totalResults: 0, | |
| resultsShared: 0, | |
| isError: true, | |
| }; | |
| } | |
| // Step 5: Validate parameters | |
| const validation = validateParameters(inputParameters, schemaResult); | |
| if (!validation.valid) { | |
| return { | |
| formatted: formatValidationError(validation.errors, spaceName), | |
| totalResults: 0, | |
| resultsShared: 0, | |
| isError: true, | |
| }; | |
| } | |
| // Step 6: Check for unknown parameters (warnings) | |
| const warnings: string[] = []; | |
| const knownParamNames = new Set(schemaResult.parameters.map((p) => p.name)); | |
| for (const key of Object.keys(inputParameters)) { | |
| if (!knownParamNames.has(key)) { | |
| warnings.push(`Unknown parameter: "${key}" (will be passed through)`); | |
| } | |
| } | |
| // Step 7: Apply default values for missing optional parameters | |
| const finalParameters = applyDefaults(inputParameters, schemaResult); | |
| // Step 8: Create Streamable HTTP connection and invoke tool (shared helper) | |
| const mcpUrl = `https://${metadata.subdomain}.hf.space/gradio_api/mcp/`; | |
| const { result } = await callGradioToolWithHeaders(mcpUrl, tool.name, finalParameters, hfToken, extra, { | |
| logProxiedReplica: true, | |
| }); | |
| // Return raw MCP result with warnings if any | |
| // This ensures the space tool behaves identically to proxied gr_* tools | |
| return { | |
| result, | |
| warnings, | |
| totalResults: 1, | |
| resultsShared: 1, | |
| isError: result.isError, | |
| }; | |
| } catch (error) { | |
| const errorMessage = error instanceof Error ? error.message : String(error); | |
| return { | |
| formatted: `Error invoking space '${spaceName}': ${errorMessage}`, | |
| totalResults: 0, | |
| resultsShared: 0, | |
| isError: true, | |
| }; | |
| } | |
| } | |
Xet Storage Details
- Size:
- 3.98 kB
- Xet hash:
- da7f4091edd8a6b74127964508e9ff4a390651d0d3950b043b069e7dca46fd36
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.