Nicer error API
Both the combination of positional argument and naming does not feel like Ruby. This change makes `is_error` argument a keyword argument called `error`. Thanks to this, the usage is more self-explanatory: ```ruby response = Response.new([], error: true) ```
This commit is contained in:
parent
33258623a7
commit
6689db2ca0
3 changed files with 94 additions and 6 deletions
|
|
@ -3,15 +3,26 @@
|
||||||
module MCP
|
module MCP
|
||||||
class Tool
|
class Tool
|
||||||
class Response
|
class Response
|
||||||
attr_reader :content, :is_error
|
NOT_GIVEN = Object.new.freeze
|
||||||
|
|
||||||
|
attr_reader :content
|
||||||
|
|
||||||
|
def initialize(content, deprecated_error = NOT_GIVEN, error: false)
|
||||||
|
if deprecated_error != NOT_GIVEN
|
||||||
|
warn("Passing `error` with the 2nd argument of `Response.new` is deprecated. Use keyword argument like `Response.new(content, error: error)` instead.", uplevel: 1)
|
||||||
|
error = deprecated_error
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(content, is_error = false)
|
|
||||||
@content = content
|
@content = content
|
||||||
@is_error = is_error
|
@error = error
|
||||||
|
end
|
||||||
|
|
||||||
|
def error?
|
||||||
|
!!@error
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_h
|
def to_h
|
||||||
{ content:, isError: is_error }.compact
|
{ content:, isError: error? }.compact
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
77
test/mcp/tool/response_test.rb
Normal file
77
test/mcp/tool/response_test.rb
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
module MCP
|
||||||
|
class Tool
|
||||||
|
class ResponseTest < ActiveSupport::TestCase
|
||||||
|
test "#initialize with content" do
|
||||||
|
content = [{
|
||||||
|
type: "text",
|
||||||
|
text: "Unauthorized",
|
||||||
|
}]
|
||||||
|
response = Response.new(content)
|
||||||
|
|
||||||
|
assert_equal content, response.content
|
||||||
|
refute response.error?
|
||||||
|
end
|
||||||
|
|
||||||
|
test "#initialize with content and error set to true" do
|
||||||
|
content = [{
|
||||||
|
type: "text",
|
||||||
|
text: "Unauthorized",
|
||||||
|
}]
|
||||||
|
response = Response.new(content, error: true)
|
||||||
|
|
||||||
|
assert_equal content, response.content
|
||||||
|
assert response.error?
|
||||||
|
end
|
||||||
|
|
||||||
|
test "#initialize with content and error explicitly set to false" do
|
||||||
|
content = [{
|
||||||
|
type: "text",
|
||||||
|
text: "Unauthorized",
|
||||||
|
}]
|
||||||
|
response = Response.new(content, error: false)
|
||||||
|
|
||||||
|
assert_equal content, response.content
|
||||||
|
refute response.error?
|
||||||
|
end
|
||||||
|
|
||||||
|
test "#error? for a standard response" do
|
||||||
|
response = Response.new(nil, error: false)
|
||||||
|
refute response.error?
|
||||||
|
end
|
||||||
|
|
||||||
|
test "#error? for an error response" do
|
||||||
|
response = Response.new(nil, error: true)
|
||||||
|
assert response.error?
|
||||||
|
end
|
||||||
|
|
||||||
|
test "#to_h for a standard response" do
|
||||||
|
content = [{
|
||||||
|
type: "text",
|
||||||
|
text: "Unauthorized",
|
||||||
|
}]
|
||||||
|
response = Response.new(content)
|
||||||
|
actual = response.to_h
|
||||||
|
|
||||||
|
assert_equal [:content, :isError].sort, actual.keys.sort
|
||||||
|
assert_equal content, actual[:content]
|
||||||
|
refute actual[:isError]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "#to_h for an error response" do
|
||||||
|
content = [{
|
||||||
|
type: "text",
|
||||||
|
text: "Unauthorized",
|
||||||
|
}]
|
||||||
|
response = Response.new(content, error: true)
|
||||||
|
actual = response.to_h
|
||||||
|
assert_equal [:content, :isError].sort, actual.keys.sort
|
||||||
|
assert_equal content, actual[:content]
|
||||||
|
assert actual[:isError]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -45,7 +45,7 @@ module MCP
|
||||||
tool = TestTool
|
tool = TestTool
|
||||||
response = tool.call(message: "test")
|
response = tool.call(message: "test")
|
||||||
assert_equal response.content, [{ type: "text", content: "OK" }]
|
assert_equal response.content, [{ type: "text", content: "OK" }]
|
||||||
assert_equal response.is_error, false
|
refute response.error?
|
||||||
end
|
end
|
||||||
|
|
||||||
test "allows declarative definition of tools as classes" do
|
test "allows declarative definition of tools as classes" do
|
||||||
|
|
@ -250,7 +250,7 @@ module MCP
|
||||||
tool = TypedTestTool
|
tool = TypedTestTool
|
||||||
response = tool.call(message: "test")
|
response = tool.call(message: "test")
|
||||||
assert_equal response.content, [{ type: "text", content: "OK" }]
|
assert_equal response.content, [{ type: "text", content: "OK" }]
|
||||||
assert_equal response.is_error, false
|
refute response.error?
|
||||||
end
|
end
|
||||||
|
|
||||||
class TestToolWithoutServerContext < Tool
|
class TestToolWithoutServerContext < Tool
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue