feat(task): add task support (SEP-1686) (#536)
Signed-off-by: jokemanfire <hu.dingyang@zte.com.cn>
This commit is contained in:
parent
eeacd1375f
commit
621c9f619e
7 changed files with 1922 additions and 57 deletions
|
|
@ -202,12 +202,35 @@
|
|||
"name": {
|
||||
"description": "The name of the tool to call",
|
||||
"type": "string"
|
||||
},
|
||||
"task": {
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
],
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"CancelTaskMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "tasks/cancel"
|
||||
},
|
||||
"CancelTaskParam": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"taskId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"taskId"
|
||||
]
|
||||
},
|
||||
"CancelledNotificationMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
|
|
@ -272,6 +295,16 @@
|
|||
"null"
|
||||
],
|
||||
"additionalProperties": true
|
||||
},
|
||||
"tasks": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/TasksCapability"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -520,6 +553,38 @@
|
|||
"name"
|
||||
]
|
||||
},
|
||||
"GetTaskInfoMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "tasks/get"
|
||||
},
|
||||
"GetTaskInfoParam": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"taskId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"taskId"
|
||||
]
|
||||
},
|
||||
"GetTaskResultMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "tasks/result"
|
||||
},
|
||||
"GetTaskResultParam": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"taskId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"taskId"
|
||||
]
|
||||
},
|
||||
"Icon": {
|
||||
"description": "A URL pointing to an icon resource or a base64-encoded data URI.\n\nClients that support rendering icons MUST support at least the following MIME types:\n- image/png - PNG images (safe, universal compatibility)\n- image/jpeg (and image/jpg) - JPEG images (safe, universal compatibility)\n\nClients that support rendering icons SHOULD also support:\n- image/svg+xml - SVG images (scalable but requires security precautions)\n- image/webp - WebP images (modern, efficient format)",
|
||||
"type": "object",
|
||||
|
|
@ -730,6 +795,18 @@
|
|||
},
|
||||
{
|
||||
"$ref": "#/definitions/CustomRequest"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/Request9"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/RequestOptionalParam5"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/Request10"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/Request11"
|
||||
}
|
||||
],
|
||||
"required": [
|
||||
|
|
@ -790,6 +867,11 @@
|
|||
"roots"
|
||||
]
|
||||
},
|
||||
"ListTasksMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "tasks/list"
|
||||
},
|
||||
"ListToolsRequestMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
|
|
@ -1168,6 +1250,38 @@
|
|||
"params"
|
||||
]
|
||||
},
|
||||
"Request10": {
|
||||
"description": "Represents a JSON-RPC request with method, parameters, and extensions.\n\nThis is the core structure for all MCP requests, containing:\n- `method`: The name of the method being called\n- `params`: The parameters for the method\n- `extensions`: Additional context data (similar to HTTP headers)",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"method": {
|
||||
"$ref": "#/definitions/GetTaskResultMethod"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/GetTaskResultParam"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
]
|
||||
},
|
||||
"Request11": {
|
||||
"description": "Represents a JSON-RPC request with method, parameters, and extensions.\n\nThis is the core structure for all MCP requests, containing:\n- `method`: The name of the method being called\n- `params`: The parameters for the method\n- `extensions`: Additional context data (similar to HTTP headers)",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"method": {
|
||||
"$ref": "#/definitions/CancelTaskMethod"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/CancelTaskParam"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
]
|
||||
},
|
||||
"Request2": {
|
||||
"description": "Represents a JSON-RPC request with method, parameters, and extensions.\n\nThis is the core structure for all MCP requests, containing:\n- `method`: The name of the method being called\n- `params`: The parameters for the method\n- `extensions`: Additional context data (similar to HTTP headers)",
|
||||
"type": "object",
|
||||
|
|
@ -1280,6 +1394,22 @@
|
|||
"params"
|
||||
]
|
||||
},
|
||||
"Request9": {
|
||||
"description": "Represents a JSON-RPC request with method, parameters, and extensions.\n\nThis is the core structure for all MCP requests, containing:\n- `method`: The name of the method being called\n- `params`: The parameters for the method\n- `extensions`: Additional context data (similar to HTTP headers)",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"method": {
|
||||
"$ref": "#/definitions/GetTaskInfoMethod"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/GetTaskInfoParam"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
]
|
||||
},
|
||||
"RequestNoParam": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -1375,6 +1505,27 @@
|
|||
"method"
|
||||
]
|
||||
},
|
||||
"RequestOptionalParam5": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"method": {
|
||||
"$ref": "#/definitions/ListTasksMethod"
|
||||
},
|
||||
"params": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PaginatedRequestParam"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method"
|
||||
]
|
||||
},
|
||||
"ResourceContents": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
|
@ -1534,6 +1685,36 @@
|
|||
"uri"
|
||||
]
|
||||
},
|
||||
"TasksCapability": {
|
||||
"description": "Task capability negotiation for SEP-1686.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cancel": {
|
||||
"description": "Whether the receiver supports `tasks/cancel`.",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"list": {
|
||||
"description": "Whether the receiver supports `tasks/list`.",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"requests": {
|
||||
"description": "Map of request category (e.g. \"tools.call\") to a boolean indicating support.",
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
],
|
||||
"additionalProperties": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"UnsubscribeRequestMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
|
|
|
|||
|
|
@ -202,12 +202,35 @@
|
|||
"name": {
|
||||
"description": "The name of the tool to call",
|
||||
"type": "string"
|
||||
},
|
||||
"task": {
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
],
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name"
|
||||
]
|
||||
},
|
||||
"CancelTaskMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "tasks/cancel"
|
||||
},
|
||||
"CancelTaskParam": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"taskId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"taskId"
|
||||
]
|
||||
},
|
||||
"CancelledNotificationMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
|
|
@ -272,6 +295,16 @@
|
|||
"null"
|
||||
],
|
||||
"additionalProperties": true
|
||||
},
|
||||
"tasks": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/TasksCapability"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -520,6 +553,38 @@
|
|||
"name"
|
||||
]
|
||||
},
|
||||
"GetTaskInfoMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "tasks/get"
|
||||
},
|
||||
"GetTaskInfoParam": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"taskId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"taskId"
|
||||
]
|
||||
},
|
||||
"GetTaskResultMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "tasks/result"
|
||||
},
|
||||
"GetTaskResultParam": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"taskId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"taskId"
|
||||
]
|
||||
},
|
||||
"Icon": {
|
||||
"description": "A URL pointing to an icon resource or a base64-encoded data URI.\n\nClients that support rendering icons MUST support at least the following MIME types:\n- image/png - PNG images (safe, universal compatibility)\n- image/jpeg (and image/jpg) - JPEG images (safe, universal compatibility)\n\nClients that support rendering icons SHOULD also support:\n- image/svg+xml - SVG images (scalable but requires security precautions)\n- image/webp - WebP images (modern, efficient format)",
|
||||
"type": "object",
|
||||
|
|
@ -730,6 +795,18 @@
|
|||
},
|
||||
{
|
||||
"$ref": "#/definitions/CustomRequest"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/Request9"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/RequestOptionalParam5"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/Request10"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/Request11"
|
||||
}
|
||||
],
|
||||
"required": [
|
||||
|
|
@ -790,6 +867,11 @@
|
|||
"roots"
|
||||
]
|
||||
},
|
||||
"ListTasksMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
"const": "tasks/list"
|
||||
},
|
||||
"ListToolsRequestMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
|
|
@ -1168,6 +1250,38 @@
|
|||
"params"
|
||||
]
|
||||
},
|
||||
"Request10": {
|
||||
"description": "Represents a JSON-RPC request with method, parameters, and extensions.\n\nThis is the core structure for all MCP requests, containing:\n- `method`: The name of the method being called\n- `params`: The parameters for the method\n- `extensions`: Additional context data (similar to HTTP headers)",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"method": {
|
||||
"$ref": "#/definitions/GetTaskResultMethod"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/GetTaskResultParam"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
]
|
||||
},
|
||||
"Request11": {
|
||||
"description": "Represents a JSON-RPC request with method, parameters, and extensions.\n\nThis is the core structure for all MCP requests, containing:\n- `method`: The name of the method being called\n- `params`: The parameters for the method\n- `extensions`: Additional context data (similar to HTTP headers)",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"method": {
|
||||
"$ref": "#/definitions/CancelTaskMethod"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/CancelTaskParam"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
]
|
||||
},
|
||||
"Request2": {
|
||||
"description": "Represents a JSON-RPC request with method, parameters, and extensions.\n\nThis is the core structure for all MCP requests, containing:\n- `method`: The name of the method being called\n- `params`: The parameters for the method\n- `extensions`: Additional context data (similar to HTTP headers)",
|
||||
"type": "object",
|
||||
|
|
@ -1280,6 +1394,22 @@
|
|||
"params"
|
||||
]
|
||||
},
|
||||
"Request9": {
|
||||
"description": "Represents a JSON-RPC request with method, parameters, and extensions.\n\nThis is the core structure for all MCP requests, containing:\n- `method`: The name of the method being called\n- `params`: The parameters for the method\n- `extensions`: Additional context data (similar to HTTP headers)",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"method": {
|
||||
"$ref": "#/definitions/GetTaskInfoMethod"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/GetTaskInfoParam"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
]
|
||||
},
|
||||
"RequestNoParam": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -1375,6 +1505,27 @@
|
|||
"method"
|
||||
]
|
||||
},
|
||||
"RequestOptionalParam5": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"method": {
|
||||
"$ref": "#/definitions/ListTasksMethod"
|
||||
},
|
||||
"params": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PaginatedRequestParam"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method"
|
||||
]
|
||||
},
|
||||
"ResourceContents": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
|
@ -1534,6 +1685,36 @@
|
|||
"uri"
|
||||
]
|
||||
},
|
||||
"TasksCapability": {
|
||||
"description": "Task capability negotiation for SEP-1686.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cancel": {
|
||||
"description": "Whether the receiver supports `tasks/cancel`.",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"list": {
|
||||
"description": "Whether the receiver supports `tasks/list`.",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"requests": {
|
||||
"description": "Map of request category (e.g. \"tools.call\") to a boolean indicating support.",
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
],
|
||||
"additionalProperties": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"UnsubscribeRequestMethod": {
|
||||
"type": "string",
|
||||
"format": "const",
|
||||
|
|
|
|||
|
|
@ -603,6 +603,18 @@
|
|||
"maxTokens"
|
||||
]
|
||||
},
|
||||
"CreateTaskResult": {
|
||||
"description": "Wrapper returned by task-augmented requests (CreateTaskResult in SEP-1686).",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task": {
|
||||
"$ref": "#/definitions/Task"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"task"
|
||||
]
|
||||
},
|
||||
"CustomNotification": {
|
||||
"description": "A catch-all notification either side can use to send custom messages to its peer.\n\nThis preserves the raw `method` name and `params` payload so handlers can\ndeserialize them into domain-specific types.",
|
||||
"type": "object",
|
||||
|
|
@ -810,6 +822,21 @@
|
|||
"messages"
|
||||
]
|
||||
},
|
||||
"GetTaskInfoResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Task"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Icon": {
|
||||
"description": "A URL pointing to an icon resource or a base64-encoded data URI.\n\nClients that support rendering icons MUST support at least the following MIME types:\n- image/png - PNG images (safe, universal compatibility)\n- image/jpeg (and image/jpg) - JPEG images (safe, universal compatibility)\n\nClients that support rendering icons SHOULD also support:\n- image/svg+xml - SVG images (scalable but requires security precautions)\n- image/webp - WebP images (modern, efficient format)",
|
||||
"type": "object",
|
||||
|
|
@ -1168,6 +1195,34 @@
|
|||
"format": "const",
|
||||
"const": "roots/list"
|
||||
},
|
||||
"ListTasksResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"nextCursor": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tasks": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Task"
|
||||
}
|
||||
},
|
||||
"total": {
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"tasks"
|
||||
]
|
||||
},
|
||||
"ListToolsResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -2255,6 +2310,16 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"tasks": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/TasksCapability"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tools": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
|
@ -2304,6 +2369,18 @@
|
|||
},
|
||||
{
|
||||
"$ref": "#/definitions/CustomResult"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/CreateTaskResult"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ListTasksResult"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/GetTaskInfoResult"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/TaskResult"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -2397,6 +2474,149 @@
|
|||
"format": "const",
|
||||
"const": "string"
|
||||
},
|
||||
"Task": {
|
||||
"description": "Primary Task object that surfaces metadata during the task lifecycle.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"createdAt": {
|
||||
"description": "ISO-8601 creation timestamp.",
|
||||
"type": "string"
|
||||
},
|
||||
"lastUpdatedAt": {
|
||||
"description": "ISO-8601 timestamp for the most recent status change.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"pollInterval": {
|
||||
"description": "Suggested polling interval (milliseconds).",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 0
|
||||
},
|
||||
"status": {
|
||||
"description": "Current lifecycle status (see [`TaskStatus`]).",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/TaskStatus"
|
||||
}
|
||||
]
|
||||
},
|
||||
"statusMessage": {
|
||||
"description": "Optional human-readable status message for UI surfaces.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"taskId": {
|
||||
"description": "Unique task identifier generated by the receiver.",
|
||||
"type": "string"
|
||||
},
|
||||
"ttl": {
|
||||
"description": "Retention window in milliseconds that the receiver agreed to honor.",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"taskId",
|
||||
"status",
|
||||
"createdAt"
|
||||
]
|
||||
},
|
||||
"TaskResult": {
|
||||
"description": "Final result for a succeeded task (returned from `tasks/result`).",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"contentType": {
|
||||
"description": "MIME type or custom content-type identifier.",
|
||||
"type": "string"
|
||||
},
|
||||
"summary": {
|
||||
"description": "Optional short summary for UI surfaces.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"description": "The actual result payload, matching the underlying request's schema."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"contentType",
|
||||
"value"
|
||||
]
|
||||
},
|
||||
"TaskStatus": {
|
||||
"description": "Canonical task lifecycle status as defined by SEP-1686.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "The receiver accepted the request and is currently working on it.",
|
||||
"type": "string",
|
||||
"const": "working"
|
||||
},
|
||||
{
|
||||
"description": "The receiver requires additional input before work can continue.",
|
||||
"type": "string",
|
||||
"const": "input_required"
|
||||
},
|
||||
{
|
||||
"description": "The underlying operation completed successfully and the result is ready.",
|
||||
"type": "string",
|
||||
"const": "completed"
|
||||
},
|
||||
{
|
||||
"description": "The underlying operation failed and will not continue.",
|
||||
"type": "string",
|
||||
"const": "failed"
|
||||
},
|
||||
{
|
||||
"description": "The task was cancelled and will not continue processing.",
|
||||
"type": "string",
|
||||
"const": "cancelled"
|
||||
}
|
||||
]
|
||||
},
|
||||
"TasksCapability": {
|
||||
"description": "Task capability negotiation for SEP-1686.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cancel": {
|
||||
"description": "Whether the receiver supports `tasks/cancel`.",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"list": {
|
||||
"description": "Whether the receiver supports `tasks/list`.",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"requests": {
|
||||
"description": "Map of request category (e.g. \"tools.call\") to a boolean indicating support.",
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
],
|
||||
"additionalProperties": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Tool": {
|
||||
"description": "A tool that can be used by a model.",
|
||||
"type": "object",
|
||||
|
|
|
|||
|
|
@ -603,6 +603,18 @@
|
|||
"maxTokens"
|
||||
]
|
||||
},
|
||||
"CreateTaskResult": {
|
||||
"description": "Wrapper returned by task-augmented requests (CreateTaskResult in SEP-1686).",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task": {
|
||||
"$ref": "#/definitions/Task"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"task"
|
||||
]
|
||||
},
|
||||
"CustomNotification": {
|
||||
"description": "A catch-all notification either side can use to send custom messages to its peer.\n\nThis preserves the raw `method` name and `params` payload so handlers can\ndeserialize them into domain-specific types.",
|
||||
"type": "object",
|
||||
|
|
@ -810,6 +822,21 @@
|
|||
"messages"
|
||||
]
|
||||
},
|
||||
"GetTaskInfoResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Task"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Icon": {
|
||||
"description": "A URL pointing to an icon resource or a base64-encoded data URI.\n\nClients that support rendering icons MUST support at least the following MIME types:\n- image/png - PNG images (safe, universal compatibility)\n- image/jpeg (and image/jpg) - JPEG images (safe, universal compatibility)\n\nClients that support rendering icons SHOULD also support:\n- image/svg+xml - SVG images (scalable but requires security precautions)\n- image/webp - WebP images (modern, efficient format)",
|
||||
"type": "object",
|
||||
|
|
@ -1168,6 +1195,34 @@
|
|||
"format": "const",
|
||||
"const": "roots/list"
|
||||
},
|
||||
"ListTasksResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"nextCursor": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tasks": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Task"
|
||||
}
|
||||
},
|
||||
"total": {
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"tasks"
|
||||
]
|
||||
},
|
||||
"ListToolsResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -2255,6 +2310,16 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"tasks": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/TasksCapability"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tools": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
|
@ -2304,6 +2369,18 @@
|
|||
},
|
||||
{
|
||||
"$ref": "#/definitions/CustomResult"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/CreateTaskResult"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ListTasksResult"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/GetTaskInfoResult"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/TaskResult"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -2397,6 +2474,149 @@
|
|||
"format": "const",
|
||||
"const": "string"
|
||||
},
|
||||
"Task": {
|
||||
"description": "Primary Task object that surfaces metadata during the task lifecycle.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"createdAt": {
|
||||
"description": "ISO-8601 creation timestamp.",
|
||||
"type": "string"
|
||||
},
|
||||
"lastUpdatedAt": {
|
||||
"description": "ISO-8601 timestamp for the most recent status change.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"pollInterval": {
|
||||
"description": "Suggested polling interval (milliseconds).",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 0
|
||||
},
|
||||
"status": {
|
||||
"description": "Current lifecycle status (see [`TaskStatus`]).",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/TaskStatus"
|
||||
}
|
||||
]
|
||||
},
|
||||
"statusMessage": {
|
||||
"description": "Optional human-readable status message for UI surfaces.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"taskId": {
|
||||
"description": "Unique task identifier generated by the receiver.",
|
||||
"type": "string"
|
||||
},
|
||||
"ttl": {
|
||||
"description": "Retention window in milliseconds that the receiver agreed to honor.",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"format": "uint64",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"taskId",
|
||||
"status",
|
||||
"createdAt"
|
||||
]
|
||||
},
|
||||
"TaskResult": {
|
||||
"description": "Final result for a succeeded task (returned from `tasks/result`).",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"contentType": {
|
||||
"description": "MIME type or custom content-type identifier.",
|
||||
"type": "string"
|
||||
},
|
||||
"summary": {
|
||||
"description": "Optional short summary for UI surfaces.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"description": "The actual result payload, matching the underlying request's schema."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"contentType",
|
||||
"value"
|
||||
]
|
||||
},
|
||||
"TaskStatus": {
|
||||
"description": "Canonical task lifecycle status as defined by SEP-1686.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "The receiver accepted the request and is currently working on it.",
|
||||
"type": "string",
|
||||
"const": "working"
|
||||
},
|
||||
{
|
||||
"description": "The receiver requires additional input before work can continue.",
|
||||
"type": "string",
|
||||
"const": "input_required"
|
||||
},
|
||||
{
|
||||
"description": "The underlying operation completed successfully and the result is ready.",
|
||||
"type": "string",
|
||||
"const": "completed"
|
||||
},
|
||||
{
|
||||
"description": "The underlying operation failed and will not continue.",
|
||||
"type": "string",
|
||||
"const": "failed"
|
||||
},
|
||||
{
|
||||
"description": "The task was cancelled and will not continue processing.",
|
||||
"type": "string",
|
||||
"const": "cancelled"
|
||||
}
|
||||
]
|
||||
},
|
||||
"TasksCapability": {
|
||||
"description": "Task capability negotiation for SEP-1686.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"cancel": {
|
||||
"description": "Whether the receiver supports `tasks/cancel`.",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"list": {
|
||||
"description": "Whether the receiver supports `tasks/list`.",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"requests": {
|
||||
"description": "Map of request category (e.g. \"tools.call\") to a boolean indicating support.",
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
],
|
||||
"additionalProperties": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Tool": {
|
||||
"description": "A tool that can be used by a model.",
|
||||
"type": "object",
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ async fn test_progress_subscriber() -> anyhow::Result<()> {
|
|||
ClientRequest::CallToolRequest(Request::new(CallToolRequestParam {
|
||||
name: "some_progress".into(),
|
||||
arguments: None,
|
||||
task: None,
|
||||
})),
|
||||
PeerRequestOptions::no_options(),
|
||||
)
|
||||
|
|
|
|||
77
crates/rmcp/tests/test_task.rs
Normal file
77
crates/rmcp/tests/test_task.rs
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
use std::{any::Any, time::Duration};
|
||||
|
||||
use rmcp::task_manager::{
|
||||
OperationDescriptor, OperationMessage, OperationProcessor, OperationResultTransport,
|
||||
};
|
||||
|
||||
struct DummyTransport {
|
||||
id: String,
|
||||
value: u32,
|
||||
}
|
||||
|
||||
impl OperationResultTransport for DummyTransport {
|
||||
fn operation_id(&self) -> &String {
|
||||
&self.id
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn executes_enqueued_future() {
|
||||
let mut processor = OperationProcessor::new();
|
||||
let descriptor = OperationDescriptor::new("op1", "dummy");
|
||||
let future = Box::pin(async {
|
||||
tokio::time::sleep(Duration::from_millis(10)).await;
|
||||
Ok(Box::new(DummyTransport {
|
||||
id: "op1".to_string(),
|
||||
value: 42,
|
||||
}) as Box<dyn OperationResultTransport>)
|
||||
});
|
||||
|
||||
processor
|
||||
.submit_operation(OperationMessage::new(descriptor, future))
|
||||
.expect("submit operation");
|
||||
|
||||
tokio::time::sleep(Duration::from_millis(30)).await;
|
||||
let results = processor.collect_completed_results();
|
||||
assert_eq!(results.len(), 1);
|
||||
let payload = results[0]
|
||||
.result
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.as_any()
|
||||
.downcast_ref::<DummyTransport>()
|
||||
.unwrap();
|
||||
assert_eq!(payload.value, 42);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn rejects_duplicate_operation_ids() {
|
||||
let mut processor = OperationProcessor::new();
|
||||
let descriptor = OperationDescriptor::new("dup", "dummy");
|
||||
let future = Box::pin(async {
|
||||
Ok(Box::new(DummyTransport {
|
||||
id: "dup".to_string(),
|
||||
value: 1,
|
||||
}) as Box<dyn OperationResultTransport>)
|
||||
});
|
||||
processor
|
||||
.submit_operation(OperationMessage::new(descriptor, future))
|
||||
.expect("first submit");
|
||||
|
||||
let descriptor_dup = OperationDescriptor::new("dup", "dummy");
|
||||
let future_dup = Box::pin(async {
|
||||
Ok(Box::new(DummyTransport {
|
||||
id: "dup".to_string(),
|
||||
value: 2,
|
||||
}) as Box<dyn OperationResultTransport>)
|
||||
});
|
||||
|
||||
let err = processor
|
||||
.submit_operation(OperationMessage::new(descriptor_dup, future_dup))
|
||||
.expect_err("duplicate should fail");
|
||||
assert!(format!("{err}").contains("already running"));
|
||||
}
|
||||
|
|
@ -320,6 +320,7 @@ async fn test_optional_i64_field_with_null_input() -> anyhow::Result<()> {
|
|||
.unwrap()
|
||||
.clone(),
|
||||
),
|
||||
task: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
|
@ -348,6 +349,7 @@ async fn test_optional_i64_field_with_null_input() -> anyhow::Result<()> {
|
|||
.unwrap()
|
||||
.clone(),
|
||||
),
|
||||
task: None,
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue