feat: SEP-1686 Tasks (#844)
finished SEP-1686 closes #421 ## Breaking Changes none ## Types of changes - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist - [x] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [x] My code follows the repository's style guidelines - [x] New and existing tests pass locally - [x] I have added appropriate error handling - [x] I have added or updated documentation as needed
This commit is contained in:
parent
35da063c23
commit
57e546d378
4 changed files with 105 additions and 10 deletions
|
|
@ -182,6 +182,12 @@ public data class CreateMessageRequest(override val params: CreateMessageRequest
|
|||
public val metadata: JsonObject?
|
||||
get() = params.metadata
|
||||
|
||||
/**
|
||||
* Task metadata, if the caller is requesting task-augmented execution.
|
||||
*/
|
||||
public val task: TaskMetadata?
|
||||
get() = params.task
|
||||
|
||||
/**
|
||||
* Metadata for this request. May include a progressToken for out-of-band progress notifications.
|
||||
*/
|
||||
|
|
@ -216,6 +222,8 @@ public data class CreateMessageRequest(override val params: CreateMessageRequest
|
|||
* @property toolChoice Optional policy controlling how the model uses the provided [tools].
|
||||
* The client MUST return an error if this field is present but the client did not advertise
|
||||
* [ClientCapabilities.Sampling.tools].
|
||||
* @property task If set, requests task-augmented execution. A receiver that supports it returns
|
||||
* a [CreateTaskResult] (result via `tasks/result`); otherwise it returns a [CreateMessageResult] directly.
|
||||
* @property meta Optional metadata for this request. May include a progressToken for
|
||||
* out-of-band progress notifications.
|
||||
*/
|
||||
|
|
@ -231,6 +239,7 @@ public data class CreateMessageRequestParams(
|
|||
val metadata: JsonObject? = null,
|
||||
val tools: List<Tool>? = null,
|
||||
val toolChoice: ToolChoice? = null,
|
||||
val task: TaskMetadata? = null,
|
||||
@SerialName("_meta")
|
||||
override val meta: RequestMeta? = null,
|
||||
) : RequestParams
|
||||
|
|
|
|||
|
|
@ -203,6 +203,12 @@ public data class CallToolRequest(override val params: CallToolRequestParams) :
|
|||
public val arguments: JsonObject?
|
||||
get() = params.arguments
|
||||
|
||||
/**
|
||||
* Task metadata, if the caller is requesting task-augmented execution.
|
||||
*/
|
||||
public val task: TaskMetadata?
|
||||
get() = params.task
|
||||
|
||||
/**
|
||||
* Metadata for this request. May include a progressToken for out-of-band progress notifications.
|
||||
*/
|
||||
|
|
@ -216,6 +222,8 @@ public data class CallToolRequest(override val params: CallToolRequestParams) :
|
|||
* @property name The name of the tool to invoke.
|
||||
* @property arguments Arguments to pass to the tool. Keys are argument names, values are the argument values.
|
||||
* The structure must match the tool's input schema.
|
||||
* @property task If set, requests task-augmented execution. A receiver that supports it returns
|
||||
* a [CreateTaskResult] (result via `tasks/result`); otherwise it returns a [CallToolResult] directly.
|
||||
* @property meta Optional metadata for this request. May include a progressToken for
|
||||
* out-of-band progress notifications.
|
||||
*/
|
||||
|
|
@ -223,6 +231,7 @@ public data class CallToolRequest(override val params: CallToolRequestParams) :
|
|||
public data class CallToolRequestParams(
|
||||
val name: String,
|
||||
val arguments: JsonObject? = null,
|
||||
val task: TaskMetadata? = null,
|
||||
@SerialName("_meta")
|
||||
override val meta: RequestMeta? = null,
|
||||
) : RequestParams
|
||||
|
|
|
|||
|
|
@ -367,6 +367,26 @@ class SamplingTest {
|
|||
decoded.toolChoice shouldBe ToolChoice(mode = ToolChoice.Mode.Required)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CreateMessageRequestParams task defaults to null and is omitted when encoding`() {
|
||||
val params = CreateMessageRequestParams(maxTokens = 100, messages = emptyList())
|
||||
params.task shouldBe null
|
||||
val encoded = McpJson.encodeToString(CreateMessageRequestParams.serializer(), params)
|
||||
assertEquals(false, "\"task\"" in encoded)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CreateMessageRequestParams round-trips task`() {
|
||||
val original = CreateMessageRequestParams(
|
||||
maxTokens = 100,
|
||||
messages = emptyList(),
|
||||
task = TaskMetadata(ttl = 60_000L),
|
||||
)
|
||||
val encoded = McpJson.encodeToString(CreateMessageRequestParams.serializer(), original)
|
||||
val decoded = McpJson.decodeFromString(CreateMessageRequestParams.serializer(), encoded)
|
||||
decoded.task shouldBe TaskMetadata(ttl = 60_000L)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `StopReason ToolUse serialises as toolUse`() {
|
||||
StopReason.ToolUse.value shouldBe "toolUse"
|
||||
|
|
|
|||
|
|
@ -319,6 +319,57 @@ class ToolsTest {
|
|||
assertEquals(ProgressToken(77), params.meta?.progressToken)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should serialize CallToolRequest with task augmentation`() {
|
||||
val request = CallToolRequest(
|
||||
CallToolRequestParams(
|
||||
name = "long-running",
|
||||
arguments = buildJsonObject { put("query", "MCP protocol") },
|
||||
task = TaskMetadata(ttl = 60_000L),
|
||||
),
|
||||
)
|
||||
|
||||
verifySerialization(
|
||||
request,
|
||||
McpJson,
|
||||
"""
|
||||
{
|
||||
"method": "tools/call",
|
||||
"params": {
|
||||
"name": "long-running",
|
||||
"arguments": {
|
||||
"query": "MCP protocol"
|
||||
},
|
||||
"task": {
|
||||
"ttl": 60000
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent(),
|
||||
)
|
||||
|
||||
assertEquals(TaskMetadata(ttl = 60_000L), request.task)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should omit task from CallToolRequest when null`() {
|
||||
val request = CallToolRequest(CallToolRequestParams(name = "plain"))
|
||||
|
||||
assertEquals(null, request.task)
|
||||
verifySerialization(
|
||||
request,
|
||||
McpJson,
|
||||
"""
|
||||
{
|
||||
"method": "tools/call",
|
||||
"params": {
|
||||
"name": "plain"
|
||||
}
|
||||
}
|
||||
""".trimIndent(),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should serialize CallToolResult with structured content`() {
|
||||
val result = CallToolResult(
|
||||
|
|
|
|||
Loading…
Reference in a new issue