agentscope-sift / node_modules /@modelcontextprotocol /sdk /dist /cjs /experimental /tasks /server.js
| ; | |
| /** | |
| * Experimental server task features for MCP SDK. | |
| * WARNING: These APIs are experimental and may change without notice. | |
| * | |
| * @experimental | |
| */ | |
| Object.defineProperty(exports, "__esModule", { value: true }); | |
| exports.ExperimentalServerTasks = void 0; | |
| const types_js_1 = require("../../types.js"); | |
| /** | |
| * Experimental task features for low-level MCP servers. | |
| * | |
| * Access via `server.experimental.tasks`: | |
| * ```typescript | |
| * const stream = server.experimental.tasks.requestStream(request, schema, options); | |
| * ``` | |
| * | |
| * For high-level server usage with task-based tools, use `McpServer.experimental.tasks` instead. | |
| * | |
| * @experimental | |
| */ | |
| class ExperimentalServerTasks { | |
| constructor(_server) { | |
| this._server = _server; | |
| } | |
| /** | |
| * Sends a request and returns an AsyncGenerator that yields response messages. | |
| * The generator is guaranteed to end with either a 'result' or 'error' message. | |
| * | |
| * This method provides streaming access to request processing, allowing you to | |
| * observe intermediate task status updates for task-augmented requests. | |
| * | |
| * @param request - The request to send | |
| * @param resultSchema - Zod schema for validating the result | |
| * @param options - Optional request options (timeout, signal, task creation params, etc.) | |
| * @returns AsyncGenerator that yields ResponseMessage objects | |
| * | |
| * @experimental | |
| */ | |
| requestStream(request, resultSchema, options) { | |
| return this._server.requestStream(request, resultSchema, options); | |
| } | |
| /** | |
| * Sends a sampling request and returns an AsyncGenerator that yields response messages. | |
| * The generator is guaranteed to end with either a 'result' or 'error' message. | |
| * | |
| * For task-augmented requests, yields 'taskCreated' and 'taskStatus' messages | |
| * before the final result. | |
| * | |
| * @example | |
| * ```typescript | |
| * const stream = server.experimental.tasks.createMessageStream({ | |
| * messages: [{ role: 'user', content: { type: 'text', text: 'Hello' } }], | |
| * maxTokens: 100 | |
| * }, { | |
| * onprogress: (progress) => { | |
| * // Handle streaming tokens via progress notifications | |
| * console.log('Progress:', progress.message); | |
| * } | |
| * }); | |
| * | |
| * for await (const message of stream) { | |
| * switch (message.type) { | |
| * case 'taskCreated': | |
| * console.log('Task created:', message.task.taskId); | |
| * break; | |
| * case 'taskStatus': | |
| * console.log('Task status:', message.task.status); | |
| * break; | |
| * case 'result': | |
| * console.log('Final result:', message.result); | |
| * break; | |
| * case 'error': | |
| * console.error('Error:', message.error); | |
| * break; | |
| * } | |
| * } | |
| * ``` | |
| * | |
| * @param params - The sampling request parameters | |
| * @param options - Optional request options (timeout, signal, task creation params, onprogress, etc.) | |
| * @returns AsyncGenerator that yields ResponseMessage objects | |
| * | |
| * @experimental | |
| */ | |
| createMessageStream(params, options) { | |
| // Access client capabilities via the server | |
| const clientCapabilities = this._server.getClientCapabilities(); | |
| // Capability check - only required when tools/toolChoice are provided | |
| if ((params.tools || params.toolChoice) && !clientCapabilities?.sampling?.tools) { | |
| throw new Error('Client does not support sampling tools capability.'); | |
| } | |
| // Message structure validation - always validate tool_use/tool_result pairs. | |
| // These may appear even without tools/toolChoice in the current request when | |
| // a previous sampling request returned tool_use and this is a follow-up with results. | |
| if (params.messages.length > 0) { | |
| const lastMessage = params.messages[params.messages.length - 1]; | |
| const lastContent = Array.isArray(lastMessage.content) ? lastMessage.content : [lastMessage.content]; | |
| const hasToolResults = lastContent.some(c => c.type === 'tool_result'); | |
| const previousMessage = params.messages.length > 1 ? params.messages[params.messages.length - 2] : undefined; | |
| const previousContent = previousMessage | |
| ? Array.isArray(previousMessage.content) | |
| ? previousMessage.content | |
| : [previousMessage.content] | |
| : []; | |
| const hasPreviousToolUse = previousContent.some(c => c.type === 'tool_use'); | |
| if (hasToolResults) { | |
| if (lastContent.some(c => c.type !== 'tool_result')) { | |
| throw new Error('The last message must contain only tool_result content if any is present'); | |
| } | |
| if (!hasPreviousToolUse) { | |
| throw new Error('tool_result blocks are not matching any tool_use from the previous message'); | |
| } | |
| } | |
| if (hasPreviousToolUse) { | |
| // Extract tool_use IDs from previous message and tool_result IDs from current message | |
| const toolUseIds = new Set(previousContent.filter(c => c.type === 'tool_use').map(c => c.id)); | |
| const toolResultIds = new Set(lastContent.filter(c => c.type === 'tool_result').map(c => c.toolUseId)); | |
| if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every(id => toolResultIds.has(id))) { | |
| throw new Error('ids of tool_result blocks and tool_use blocks from previous message do not match'); | |
| } | |
| } | |
| } | |
| return this.requestStream({ | |
| method: 'sampling/createMessage', | |
| params | |
| }, types_js_1.CreateMessageResultSchema, options); | |
| } | |
| /** | |
| * Sends an elicitation request and returns an AsyncGenerator that yields response messages. | |
| * The generator is guaranteed to end with either a 'result' or 'error' message. | |
| * | |
| * For task-augmented requests (especially URL-based elicitation), yields 'taskCreated' | |
| * and 'taskStatus' messages before the final result. | |
| * | |
| * @example | |
| * ```typescript | |
| * const stream = server.experimental.tasks.elicitInputStream({ | |
| * mode: 'url', | |
| * message: 'Please authenticate', | |
| * elicitationId: 'auth-123', | |
| * url: 'https://example.com/auth' | |
| * }, { | |
| * task: { ttl: 300000 } // Task-augmented for long-running auth flow | |
| * }); | |
| * | |
| * for await (const message of stream) { | |
| * switch (message.type) { | |
| * case 'taskCreated': | |
| * console.log('Task created:', message.task.taskId); | |
| * break; | |
| * case 'taskStatus': | |
| * console.log('Task status:', message.task.status); | |
| * break; | |
| * case 'result': | |
| * console.log('User action:', message.result.action); | |
| * break; | |
| * case 'error': | |
| * console.error('Error:', message.error); | |
| * break; | |
| * } | |
| * } | |
| * ``` | |
| * | |
| * @param params - The elicitation request parameters | |
| * @param options - Optional request options (timeout, signal, task creation params, etc.) | |
| * @returns AsyncGenerator that yields ResponseMessage objects | |
| * | |
| * @experimental | |
| */ | |
| elicitInputStream(params, options) { | |
| // Access client capabilities via the server | |
| const clientCapabilities = this._server.getClientCapabilities(); | |
| const mode = params.mode ?? 'form'; | |
| // Capability check based on mode | |
| switch (mode) { | |
| case 'url': { | |
| if (!clientCapabilities?.elicitation?.url) { | |
| throw new Error('Client does not support url elicitation.'); | |
| } | |
| break; | |
| } | |
| case 'form': { | |
| if (!clientCapabilities?.elicitation?.form) { | |
| throw new Error('Client does not support form elicitation.'); | |
| } | |
| break; | |
| } | |
| } | |
| // Normalize params to ensure mode is set for form mode (defaults to 'form' per spec) | |
| const normalizedParams = mode === 'form' && params.mode === undefined ? { ...params, mode: 'form' } : params; | |
| // Cast to ServerRequest needed because TypeScript can't narrow the union type | |
| // based on the discriminated 'method' field when constructing the object literal | |
| return this.requestStream({ | |
| method: 'elicitation/create', | |
| params: normalizedParams | |
| }, types_js_1.ElicitResultSchema, options); | |
| } | |
| /** | |
| * Gets the current status of a task. | |
| * | |
| * @param taskId - The task identifier | |
| * @param options - Optional request options | |
| * @returns The task status | |
| * | |
| * @experimental | |
| */ | |
| async getTask(taskId, options) { | |
| return this._server.getTask({ taskId }, options); | |
| } | |
| /** | |
| * Retrieves the result of a completed task. | |
| * | |
| * @param taskId - The task identifier | |
| * @param resultSchema - Zod schema for validating the result | |
| * @param options - Optional request options | |
| * @returns The task result | |
| * | |
| * @experimental | |
| */ | |
| async getTaskResult(taskId, resultSchema, options) { | |
| return this._server.getTaskResult({ taskId }, resultSchema, options); | |
| } | |
| /** | |
| * Lists tasks with optional pagination. | |
| * | |
| * @param cursor - Optional pagination cursor | |
| * @param options - Optional request options | |
| * @returns List of tasks with optional next cursor | |
| * | |
| * @experimental | |
| */ | |
| async listTasks(cursor, options) { | |
| return this._server.listTasks(cursor ? { cursor } : undefined, options); | |
| } | |
| /** | |
| * Cancels a running task. | |
| * | |
| * @param taskId - The task identifier | |
| * @param options - Optional request options | |
| * | |
| * @experimental | |
| */ | |
| async cancelTask(taskId, options) { | |
| return this._server.cancelTask({ taskId }, options); | |
| } | |
| } | |
| exports.ExperimentalServerTasks = ExperimentalServerTasks; | |
| //# sourceMappingURL=server.js.map |