-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathinterfaces.ts
More file actions
286 lines (258 loc) · 10.2 KB
/
interfaces.ts
File metadata and controls
286 lines (258 loc) · 10.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/**
* Experimental task interfaces for MCP SDK.
* WARNING: These APIs are experimental and may change without notice.
*/
import {
Task,
RequestId,
Result,
JSONRPCRequest,
JSONRPCNotification,
JSONRPCResultResponse,
JSONRPCErrorResponse,
ServerRequest,
ServerNotification,
CallToolResult,
GetTaskResult,
ToolExecution,
Request
} from '../../types.js';
import { CreateTaskResult } from './types.js';
import type { RequestHandlerExtra, RequestTaskStore } from '../../shared/protocol.js';
import type { ZodRawShapeCompat, AnySchema, ShapeOutput } from '../../server/zod-compat.js';
// ============================================================================
// Task Handler Types (for registerToolTask)
// ============================================================================
/**
* Extended handler extra with task store for task creation.
* @experimental
*/
export interface CreateTaskRequestHandlerExtra extends RequestHandlerExtra<ServerRequest, ServerNotification> {
taskStore: RequestTaskStore;
}
/**
* Extended handler extra with task ID and store for task operations.
* @experimental
*/
export interface TaskRequestHandlerExtra extends RequestHandlerExtra<ServerRequest, ServerNotification> {
taskId: string;
taskStore: RequestTaskStore;
}
/**
* Base callback type for tool handlers.
* @experimental
*/
export type BaseToolCallback<
SendResultT extends Result,
ExtraT extends RequestHandlerExtra<ServerRequest, ServerNotification>,
Args extends undefined | ZodRawShapeCompat | AnySchema = undefined
> = Args extends ZodRawShapeCompat
? (args: ShapeOutput<Args>, extra: ExtraT) => SendResultT | Promise<SendResultT>
: Args extends AnySchema
? (args: unknown, extra: ExtraT) => SendResultT | Promise<SendResultT>
: (extra: ExtraT) => SendResultT | Promise<SendResultT>;
/**
* Handler for creating a task.
* @experimental
*/
export type CreateTaskRequestHandler<
SendResultT extends Result,
Args extends undefined | ZodRawShapeCompat | AnySchema = undefined
> = BaseToolCallback<SendResultT, CreateTaskRequestHandlerExtra, Args>;
/**
* Handler for task operations (get, getResult).
* @experimental
*/
export type TaskRequestHandler<SendResultT extends Result> = (extra: TaskRequestHandlerExtra) => SendResultT | Promise<SendResultT>;
/**
* Interface for task-based tool handlers.
* @experimental
*/
export interface ToolTaskHandler<Args extends undefined | ZodRawShapeCompat | AnySchema = undefined> {
createTask: CreateTaskRequestHandler<CreateTaskResult, Args>;
getTask: TaskRequestHandler<GetTaskResult>;
getTaskResult: TaskRequestHandler<CallToolResult>;
}
/**
* Task-specific execution configuration.
* taskSupport cannot be 'forbidden' for task-based tools.
* @experimental
*/
export type TaskToolExecution<TaskSupport = ToolExecution['taskSupport']> = Omit<ToolExecution, 'taskSupport'> & {
taskSupport: TaskSupport extends 'forbidden' | undefined ? never : TaskSupport;
};
/**
* Represents a message queued for side-channel delivery via tasks/result.
*
* This is a serializable data structure that can be stored in external systems.
* All fields are JSON-serializable.
*/
export type QueuedMessage = QueuedRequest | QueuedNotification | QueuedResponse | QueuedError;
export interface BaseQueuedMessage {
/** Type of message */
type: string;
/** When the message was queued (milliseconds since epoch) */
timestamp: number;
}
export interface QueuedRequest extends BaseQueuedMessage {
type: 'request';
/** The actual JSONRPC request */
message: JSONRPCRequest;
}
export interface QueuedNotification extends BaseQueuedMessage {
type: 'notification';
/** The actual JSONRPC notification */
message: JSONRPCNotification;
}
export interface QueuedResponse extends BaseQueuedMessage {
type: 'response';
/** The actual JSONRPC response */
message: JSONRPCResultResponse;
}
export interface QueuedError extends BaseQueuedMessage {
type: 'error';
/** The actual JSONRPC error */
message: JSONRPCErrorResponse;
}
/**
* Interface for managing per-task FIFO message queues.
*
* Similar to TaskStore, this allows pluggable queue implementations
* (in-memory, Redis, other distributed queues, etc.).
*
* Each method accepts taskId and optional sessionId parameters to enable
* a single queue instance to manage messages for multiple tasks, with
* isolation based on task ID and session ID.
*
* All methods are async to support external storage implementations.
* All data in QueuedMessage must be JSON-serializable.
*
* @experimental
*/
export interface TaskMessageQueue {
/**
* Adds a message to the end of the queue for a specific task.
* Atomically checks queue size and throws if maxSize would be exceeded.
* @param taskId The task identifier
* @param message The message to enqueue
* @param sessionId Optional session ID for binding the operation to a specific session
* @param maxSize Optional maximum queue size - if specified and queue is full, throws an error
* @throws Error if maxSize is specified and would be exceeded
*/
enqueue(taskId: string, message: QueuedMessage, sessionId?: string, maxSize?: number): Promise<void>;
/**
* Removes and returns the first message from the queue for a specific task.
* @param taskId The task identifier
* @param sessionId Optional session ID for binding the query to a specific session
* @returns The first message, or undefined if the queue is empty
*/
dequeue(taskId: string, sessionId?: string): Promise<QueuedMessage | undefined>;
/**
* Removes and returns all messages from the queue for a specific task.
* Used when tasks are cancelled or failed to clean up pending messages.
* @param taskId The task identifier
* @param sessionId Optional session ID for binding the query to a specific session
* @returns Array of all messages that were in the queue
*/
dequeueAll(taskId: string, sessionId?: string): Promise<QueuedMessage[]>;
}
/**
* Task creation options.
* @experimental
*/
export interface CreateTaskOptions {
/**
* Time in milliseconds to keep task results available after completion.
* If null, the task has unlimited lifetime until manually cleaned up.
*/
ttl?: number | null;
/**
* Time in milliseconds to wait between task status requests.
*/
pollInterval?: number;
/**
* Additional context to pass to the task store.
*/
context?: Record<string, unknown>;
}
/**
* Interface for storing and retrieving task state and results.
*
* Similar to Transport, this allows pluggable task storage implementations
* (in-memory, database, distributed cache, etc.).
*
* @experimental
*/
export interface TaskStore {
/**
* Creates a new task with the given creation parameters and original request.
* The implementation must generate a unique taskId and createdAt timestamp.
*
* TTL Management:
* - The implementation receives the TTL suggested by the requestor via taskParams.ttl
* - The implementation MAY override the requested TTL (e.g., to enforce limits)
* - The actual TTL used MUST be returned in the Task object
* - Null TTL indicates unlimited task lifetime (no automatic cleanup)
* - Cleanup SHOULD occur automatically after TTL expires, regardless of task status
*
* @param taskParams - The task creation parameters from the request (ttl, pollInterval)
* @param requestId - The JSON-RPC request ID
* @param request - The original request that triggered task creation
* @param sessionId - Optional session ID for binding the task to a specific session
* @returns The created task object
*/
createTask(taskParams: CreateTaskOptions, requestId: RequestId, request: Request, sessionId?: string): Promise<Task>;
/**
* Gets the current status of a task.
*
* @param taskId - The task identifier
* @param sessionId - Optional session ID for binding the query to a specific session
* @returns The task object, or null if it does not exist
*/
getTask(taskId: string, sessionId?: string): Promise<Task | null>;
/**
* Stores the result of a task and sets its final status.
*
* @param taskId - The task identifier
* @param status - The final status: 'completed' for success, 'failed' for errors
* @param result - The result to store
* @param sessionId - Optional session ID for binding the operation to a specific session
*/
storeTaskResult(taskId: string, status: 'completed' | 'failed', result: Result, sessionId?: string): Promise<void>;
/**
* Retrieves the stored result of a task.
*
* @param taskId - The task identifier
* @param sessionId - Optional session ID for binding the query to a specific session
* @returns The stored result
*/
getTaskResult(taskId: string, sessionId?: string): Promise<Result>;
/**
* Updates a task's status (e.g., to 'cancelled', 'failed', 'completed').
*
* @param taskId - The task identifier
* @param status - The new status
* @param statusMessage - Optional diagnostic message for failed tasks or other status information
* @param sessionId - Optional session ID for binding the operation to a specific session
*/
updateTaskStatus(taskId: string, status: Task['status'], statusMessage?: string, sessionId?: string): Promise<void>;
/**
* Lists tasks, optionally starting from a pagination cursor.
*
* @param cursor - Optional cursor for pagination
* @param sessionId - Optional session ID for binding the query to a specific session
* @returns An object containing the tasks array and an optional nextCursor
*/
listTasks(cursor?: string, sessionId?: string): Promise<{ tasks: Task[]; nextCursor?: string }>;
}
/**
* 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: Task['status']): boolean {
return status === 'completed' || status === 'failed' || status === 'cancelled';
}