mirror of
https://github.com/tvytlx/ai-agent-deep-dive.git
synced 2026-04-05 00:24:50 +08:00
Add extracted source directory and README navigation
This commit is contained in:
184
extracted-source/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/client.js
generated
vendored
Normal file
184
extracted-source/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/client.js
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* Experimental client task features for MCP SDK.
|
||||
* WARNING: These APIs are experimental and may change without notice.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
import { CallToolResultSchema, McpError, ErrorCode } from '../../types.js';
|
||||
/**
|
||||
* Experimental task features for MCP clients.
|
||||
*
|
||||
* Access via `client.experimental.tasks`:
|
||||
* ```typescript
|
||||
* const stream = client.experimental.tasks.callToolStream({ name: 'tool', arguments: {} });
|
||||
* const task = await client.experimental.tasks.getTask(taskId);
|
||||
* ```
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export class ExperimentalClientTasks {
|
||||
constructor(_client) {
|
||||
this._client = _client;
|
||||
}
|
||||
/**
|
||||
* Calls a tool 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 tool execution, allowing you to
|
||||
* observe intermediate task status updates for long-running tool calls.
|
||||
* Automatically validates structured output if the tool has an outputSchema.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const stream = client.experimental.tasks.callToolStream({ name: 'myTool', arguments: {} });
|
||||
* for await (const message of stream) {
|
||||
* switch (message.type) {
|
||||
* case 'taskCreated':
|
||||
* console.log('Tool execution started:', message.task.taskId);
|
||||
* break;
|
||||
* case 'taskStatus':
|
||||
* console.log('Tool status:', message.task.status);
|
||||
* break;
|
||||
* case 'result':
|
||||
* console.log('Tool result:', message.result);
|
||||
* break;
|
||||
* case 'error':
|
||||
* console.error('Tool error:', message.error);
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param params - Tool call parameters (name and arguments)
|
||||
* @param resultSchema - Zod schema for validating the result (defaults to CallToolResultSchema)
|
||||
* @param options - Optional request options (timeout, signal, task creation params, etc.)
|
||||
* @returns AsyncGenerator that yields ResponseMessage objects
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
async *callToolStream(params, resultSchema = CallToolResultSchema, options) {
|
||||
// Access Client's internal methods
|
||||
const clientInternal = this._client;
|
||||
// Add task creation parameters if server supports it and not explicitly provided
|
||||
const optionsWithTask = {
|
||||
...options,
|
||||
// We check if the tool is known to be a task during auto-configuration, but assume
|
||||
// the caller knows what they're doing if they pass this explicitly
|
||||
task: options?.task ?? (clientInternal.isToolTask(params.name) ? {} : undefined)
|
||||
};
|
||||
const stream = clientInternal.requestStream({ method: 'tools/call', params }, resultSchema, optionsWithTask);
|
||||
// Get the validator for this tool (if it has an output schema)
|
||||
const validator = clientInternal.getToolOutputValidator(params.name);
|
||||
// Iterate through the stream and validate the final result if needed
|
||||
for await (const message of stream) {
|
||||
// If this is a result message and the tool has an output schema, validate it
|
||||
if (message.type === 'result' && validator) {
|
||||
const result = message.result;
|
||||
// If tool has outputSchema, it MUST return structuredContent (unless it's an error)
|
||||
if (!result.structuredContent && !result.isError) {
|
||||
yield {
|
||||
type: 'error',
|
||||
error: new McpError(ErrorCode.InvalidRequest, `Tool ${params.name} has an output schema but did not return structured content`)
|
||||
};
|
||||
return;
|
||||
}
|
||||
// Only validate structured content if present (not when there's an error)
|
||||
if (result.structuredContent) {
|
||||
try {
|
||||
// Validate the structured content against the schema
|
||||
const validationResult = validator(result.structuredContent);
|
||||
if (!validationResult.valid) {
|
||||
yield {
|
||||
type: 'error',
|
||||
error: new McpError(ErrorCode.InvalidParams, `Structured content does not match the tool's output schema: ${validationResult.errorMessage}`)
|
||||
};
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof McpError) {
|
||||
yield { type: 'error', error };
|
||||
return;
|
||||
}
|
||||
yield {
|
||||
type: 'error',
|
||||
error: new McpError(ErrorCode.InvalidParams, `Failed to validate structured content: ${error instanceof Error ? error.message : String(error)}`)
|
||||
};
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Yield the message (either validated result or any other message type)
|
||||
yield message;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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._client.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) {
|
||||
// Delegate to the client's underlying Protocol method
|
||||
return this._client.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) {
|
||||
// Delegate to the client's underlying Protocol method
|
||||
return this._client.listTasks(cursor ? { cursor } : undefined, options);
|
||||
}
|
||||
/**
|
||||
* Cancels a running task.
|
||||
*
|
||||
* @param taskId - The task identifier
|
||||
* @param options - Optional request options
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
async cancelTask(taskId, options) {
|
||||
// Delegate to the client's underlying Protocol method
|
||||
return this._client.cancelTask({ taskId }, options);
|
||||
}
|
||||
/**
|
||||
* 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._client.requestStream(request, resultSchema, options);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=client.js.map
|
||||
64
extracted-source/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
generated
vendored
Normal file
64
extracted-source/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Experimental task capability assertion helpers.
|
||||
* WARNING: These APIs are experimental and may change without notice.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
/**
|
||||
* Asserts that task creation is supported for tools/call.
|
||||
* Used by Client.assertTaskCapability and Server.assertTaskHandlerCapability.
|
||||
*
|
||||
* @param requests - The task requests capability object
|
||||
* @param method - The method being checked
|
||||
* @param entityName - 'Server' or 'Client' for error messages
|
||||
* @throws Error if the capability is not supported
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export function assertToolsCallTaskCapability(requests, method, entityName) {
|
||||
if (!requests) {
|
||||
throw new Error(`${entityName} does not support task creation (required for ${method})`);
|
||||
}
|
||||
switch (method) {
|
||||
case 'tools/call':
|
||||
if (!requests.tools?.call) {
|
||||
throw new Error(`${entityName} does not support task creation for tools/call (required for ${method})`);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Method doesn't support tasks, which is fine - no error
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Asserts that task creation is supported for sampling/createMessage or elicitation/create.
|
||||
* Used by Server.assertTaskCapability and Client.assertTaskHandlerCapability.
|
||||
*
|
||||
* @param requests - The task requests capability object
|
||||
* @param method - The method being checked
|
||||
* @param entityName - 'Server' or 'Client' for error messages
|
||||
* @throws Error if the capability is not supported
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export function assertClientRequestTaskCapability(requests, method, entityName) {
|
||||
if (!requests) {
|
||||
throw new Error(`${entityName} does not support task creation (required for ${method})`);
|
||||
}
|
||||
switch (method) {
|
||||
case 'sampling/createMessage':
|
||||
if (!requests.sampling?.createMessage) {
|
||||
throw new Error(`${entityName} does not support task creation for sampling/createMessage (required for ${method})`);
|
||||
}
|
||||
break;
|
||||
case 'elicitation/create':
|
||||
if (!requests.elicitation?.create) {
|
||||
throw new Error(`${entityName} does not support task creation for elicitation/create (required for ${method})`);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Method doesn't support tasks, which is fine - no error
|
||||
break;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=helpers.js.map
|
||||
16
extracted-source/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
generated
vendored
Normal file
16
extracted-source/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Experimental task interfaces for MCP SDK.
|
||||
* WARNING: These APIs are experimental and may change without notice.
|
||||
*/
|
||||
/**
|
||||
* Checks if a task status represents a terminal state.
|
||||
* Terminal states are those where the task has finished and will not change.
|
||||
*
|
||||
* @param status - The task status to check
|
||||
* @returns True if the status is terminal (completed, failed, or cancelled)
|
||||
* @experimental
|
||||
*/
|
||||
export function isTerminal(status) {
|
||||
return status === 'completed' || status === 'failed' || status === 'cancelled';
|
||||
}
|
||||
//# sourceMappingURL=interfaces.js.map
|
||||
246
extracted-source/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
generated
vendored
Normal file
246
extracted-source/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
generated
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
/**
|
||||
* Experimental server task features for MCP SDK.
|
||||
* WARNING: These APIs are experimental and may change without notice.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
import { CreateMessageResultSchema, ElicitResultSchema } from '../../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
|
||||
*/
|
||||
export 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
|
||||
}, 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
|
||||
}, 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);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=server.js.map
|
||||
Reference in New Issue
Block a user