feat: type capability results

This commit is contained in:
lda
2026-07-31 14:35:06 +07:00 Verified
parent c96fee4e7d
commit 82f764f7a6
11 changed files with 423 additions and 136 deletions
+2
View File
@@ -84,6 +84,8 @@ async def test_inspect_capability_returns_detail_with_wrapper_hints(
detail = await api.inspect_capability(qualified_name="demo.personal.echo_tool")
assert detail["name"] == "demo.personal.echo_tool"
assert detail["source_id"] == "demo.personal"
assert detail["kind"] == "node_spec"
assert "wrapper_hints" in detail
hints = detail["wrapper_hints"]
assert hints["capability_name"] == "demo.personal.echo_tool"
+44
View File
@@ -163,6 +163,50 @@ async def test_rpc_health_and_capability_methods(tmp_path) -> None:
assert called["result"]["output"] == {"value": "hello direct rpc"}
async def test_rpc_capability_methods_preserve_saved_wrapper_fields(tmp_path) -> None:
server = build_local_static_workflow_server(tmp_path / "store")
await server.api.create_artifact_from_plan(
artifact_id="rpc_wrapper",
version=1,
title="RPC Wrapper",
kind="wrapper",
plan=_constant_plan(),
outcomes=["ok"],
)
app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app)
async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
listed = await _rpc(
client,
"workflow.capabilities.list",
{"source_id": "workflow", "limit": 10},
)
inspected = await _rpc(
client,
"workflow.capabilities.inspect",
{"qualified_name": "workflow.rpc_wrapper.v1"},
)
called = await _rpc(
client,
"workflow.capabilities.call",
{
"qualified_name": "workflow.rpc_wrapper.v1",
"payload": {},
},
)
wrapper = listed["result"]["capabilities"][0]
assert wrapper["kind"] == "wrapper_artifact"
assert wrapper["artifact_id"] == "rpc_wrapper"
assert wrapper["version"] == 1
assert wrapper["title"] == "RPC Wrapper"
assert inspected["result"]["kind"] == "wrapper_artifact"
assert inspected["result"]["artifact_id"] == "rpc_wrapper"
assert "required_capabilities" in inspected["result"]
assert called["result"]["kind"] == "wrapper_artifact"
assert called["result"]["output"] == {"result": "hello over rpc"}
async def test_rpc_unknown_method_returns_json_rpc_error(tmp_path) -> None:
server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server)
@@ -46,6 +46,77 @@ def test_openrpc_exposes_typed_health_result(
)
def test_openrpc_exposes_typed_capability_list_result(
openrpc_document: dict[str, Any],
) -> None:
_assert_result_component(
openrpc_document,
method_name="workflow.capabilities.list",
component_name="ListCapabilitiesResult",
properties={"capabilities", "next_cursor", "total"},
)
capabilities = openrpc_document["components"]["schemas"]["ListCapabilitiesResult"][
"properties"
]["capabilities"]
assert capabilities["items"] == {
"anyOf": [
{"$ref": "#/components/schemas/NodeSpecCapabilitySummary"},
{"$ref": "#/components/schemas/WrapperArtifactCapabilitySummary"},
]
}
def test_openrpc_exposes_typed_capability_inspect_result(
openrpc_document: dict[str, Any],
) -> None:
method = _method_by_name(openrpc_document, "workflow.capabilities.inspect")
assert method["result"]["schema"] == {
"$ref": "#/components/schemas/InspectCapabilityResult"
}
schemas = openrpc_document["components"]["schemas"]
assert schemas["InspectCapabilityResult"] == {
"anyOf": [
{"$ref": "#/components/schemas/NodeSpecCapabilityDetail"},
{"$ref": "#/components/schemas/WrapperArtifactCapabilityDetail"},
]
}
assert schemas["NodeSpecCapabilityDetail"]["properties"]["wrapper_hints"] == {
"$ref": "#/components/schemas/WrapperAuthoringHintsPayload"
}
assert schemas["NodeSpecCapabilityDetail"]["properties"]["kind"]["const"] == (
"node_spec"
)
assert (
schemas["WrapperArtifactCapabilityDetail"]["properties"]["kind"]["const"]
== "wrapper_artifact"
)
assert schemas["WrapperArtifactCapabilityDetail"]["properties"][
"required_capabilities"
]["additionalProperties"] == {
"$ref": "#/components/schemas/RequiredCapabilityPayload"
}
def test_openrpc_exposes_typed_capability_call_result(
openrpc_document: dict[str, Any],
) -> None:
_assert_result_component(
openrpc_document,
method_name="workflow.capabilities.call",
component_name="CapabilityCallResult",
properties={
"qualified_name",
"source_id",
"kind",
"deployment_id",
"outcome",
"output",
"diagnostics",
},
)
@pytest.mark.parametrize(
("method_name", "component_name", "properties"),
[