feat: add tool execution properties to Tool (#567)
closes #543 ## How Has This Been Tested? unit ## Breaking Changes binary compatibility in the Tool class ## 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 - [ ] I have added appropriate error handling - [ ] I have added or updated documentation as needed --------- Co-authored-by: Konstantin Pavlov <1517853+kpavlov@users.noreply.github.com>
This commit is contained in:
parent
0b39f57cff
commit
338f94804f
3 changed files with 188 additions and 8 deletions
|
|
@ -1618,7 +1618,7 @@ public fun Tool(
|
|||
title,
|
||||
annotations,
|
||||
icons,
|
||||
_meta,
|
||||
meta = _meta,
|
||||
)
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ public fun CallToolResult.Companion.error(content: String, meta: JsonObject? = n
|
|||
* @property icons Optional set of sized icons that clients can display in their user interface.
|
||||
* Clients MUST support at least PNG and JPEG formats.
|
||||
* Clients SHOULD also support SVG and WebP formats.
|
||||
* @property execution Optional execution-related properties for this tool,
|
||||
* such as task-augmented execution support.
|
||||
* @property meta Optional metadata for this tool.
|
||||
*/
|
||||
@Serializable
|
||||
|
|
@ -66,6 +68,7 @@ public data class Tool(
|
|||
val title: String? = null,
|
||||
val annotations: ToolAnnotations? = null,
|
||||
val icons: List<Icon>? = null,
|
||||
val execution: ToolExecution? = null,
|
||||
@SerialName("_meta")
|
||||
override val meta: JsonObject? = null,
|
||||
) : WithMeta
|
||||
|
|
@ -92,6 +95,38 @@ public data class ToolSchema(
|
|||
val type: String = "object"
|
||||
}
|
||||
|
||||
/**
|
||||
* Execution-related properties for a tool.
|
||||
*
|
||||
* @property taskSupport Indicates whether this tool supports task-augmented execution.
|
||||
* This allows clients to handle long-running operations through polling the task system.
|
||||
* If omitted (`null`), consumers should treat it as [TaskSupport.Forbidden] per the spec.
|
||||
*/
|
||||
@Serializable
|
||||
public data class ToolExecution(val taskSupport: TaskSupport? = null)
|
||||
|
||||
/**
|
||||
* Indicates whether a tool supports task-augmented execution.
|
||||
*
|
||||
* - [Forbidden]: Tool does not support task-augmented execution (default when absent).
|
||||
* - [Optional]: Tool may support task-augmented execution.
|
||||
* - [Required]: Tool requires task-augmented execution.
|
||||
*/
|
||||
@Serializable
|
||||
public enum class TaskSupport {
|
||||
/** Tool does not support task-augmented execution. */
|
||||
@SerialName("forbidden")
|
||||
Forbidden,
|
||||
|
||||
/** Tool may support task-augmented execution. */
|
||||
@SerialName("optional")
|
||||
Optional,
|
||||
|
||||
/** Tool requires task-augmented execution. */
|
||||
@SerialName("required")
|
||||
Required,
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional properties describing a Tool to clients.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -475,6 +475,102 @@ class ToolsTest {
|
|||
assertEquals(null, result.structuredContent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should serialize ToolExecution with taskSupport`() {
|
||||
val execution = ToolExecution(taskSupport = TaskSupport.Required)
|
||||
|
||||
verifySerialization(
|
||||
execution,
|
||||
McpJson,
|
||||
"""
|
||||
{
|
||||
"taskSupport": "required"
|
||||
}
|
||||
""".trimIndent(),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should serialize ToolExecution without taskSupport`() {
|
||||
val execution = ToolExecution()
|
||||
|
||||
verifySerialization(
|
||||
execution,
|
||||
McpJson,
|
||||
"{}",
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should deserialize ToolExecution with taskSupport`() {
|
||||
val json = """
|
||||
{
|
||||
"taskSupport": "optional"
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
val execution = verifyDeserialization<ToolExecution>(McpJson, json)
|
||||
|
||||
assertEquals(TaskSupport.Optional, execution.taskSupport)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should deserialize ToolExecution without taskSupport`() {
|
||||
val json = "{}"
|
||||
|
||||
val execution = verifyDeserialization<ToolExecution>(McpJson, json)
|
||||
|
||||
assertEquals(null, execution.taskSupport)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should serialize Tool with execution`() {
|
||||
val tool = Tool(
|
||||
name = "long-running-task",
|
||||
inputSchema = ToolSchema(),
|
||||
description = "A tool that supports task-augmented execution",
|
||||
execution = ToolExecution(taskSupport = TaskSupport.Required),
|
||||
)
|
||||
|
||||
verifySerialization(
|
||||
tool,
|
||||
McpJson,
|
||||
"""
|
||||
{
|
||||
"name": "long-running-task",
|
||||
"inputSchema": {
|
||||
"type": "object"
|
||||
},
|
||||
"description": "A tool that supports task-augmented execution",
|
||||
"execution": {
|
||||
"taskSupport": "required"
|
||||
}
|
||||
}
|
||||
""".trimIndent(),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should deserialize Tool with execution`() {
|
||||
val json = """
|
||||
{
|
||||
"name": "long-running-task",
|
||||
"inputSchema": {
|
||||
"type": "object"
|
||||
},
|
||||
"execution": {
|
||||
"taskSupport": "forbidden"
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
val tool = verifyDeserialization<Tool>(McpJson, json)
|
||||
|
||||
assertEquals("long-running-task", tool.name)
|
||||
assertNotNull(tool.execution)
|
||||
assertEquals(TaskSupport.Forbidden, tool.execution.taskSupport)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should serialize tool schema type even when defaults disabled`() {
|
||||
val tool = weatherTool()
|
||||
|
|
|
|||
Loading…
Reference in a new issue