Files
cleveragents-core/features/tool_runtime.feature
T
Jeff (CTO) 18482b938f
CI / typecheck (push) Waiting to run
CI / lint (push) Waiting to run
CI / security (push) Waiting to run
CI / quality (push) Waiting to run
CI / unit_tests (push) Waiting to run
CI / integration_tests (push) Waiting to run
CI / coverage (push) Blocked by required conditions
CI / build (push) Waiting to run
CI / docker (push) Blocked by required conditions
CI / lint (pull_request) Successful in 14s
CI / typecheck (pull_request) Successful in 27s
CI / security (pull_request) Successful in 22s
CI / quality (pull_request) Successful in 15s
CI / integration_tests (pull_request) Successful in 4m32s
CI / build (pull_request) Successful in 16s
CI / unit_tests (pull_request) Successful in 9m45s
CI / coverage (pull_request) Successful in 6m53s
CI / docker (pull_request) Successful in 39s
feat(tool): add tool runtime core
2026-02-14 13:46:10 -05:00

212 lines
7.8 KiB
Gherkin

Feature: Tool Runtime Core
As a developer
I want a tool runtime with registry, runner, and lifecycle management
So that tools can be registered, discovered, activated, executed, and deactivated
# ---- Tool Registration ----
Scenario: Register a tool in the registry
Given a tool registry
And a tool spec named "test/echo" with a handler
When I register the tool spec
Then the tool should be in the registry
Scenario: Get a registered tool by name
Given a tool registry
And a registered tool spec named "test/echo"
When I get the tool by name "test/echo"
Then the retrieved tool spec name should be "test/echo"
Scenario: List all tools in the registry
Given a tool registry
And a registered tool spec named "test/alpha"
And a registered tool spec named "test/beta"
When I list all tools
Then the tool list should contain 2 tools
Scenario: List tools filtered by namespace
Given a tool registry
And a registered tool spec named "ns1/tool-a"
And a registered tool spec named "ns2/tool-b"
And a registered tool spec named "ns1/tool-c"
When I list tools with namespace "ns1"
Then the tool list should contain 2 tools
Scenario: Remove a tool from the registry
Given a tool registry
And a registered tool spec named "test/remove-me"
When I remove the tool "test/remove-me"
Then the removal should succeed
And getting "test/remove-me" should return None
# ---- Missing Tool Errors ----
Scenario: Get a missing tool returns None
Given a tool registry
When I get the tool by name "test/nonexistent"
Then the retrieved tool spec should be None
Scenario: Remove a missing tool returns False
Given a tool registry
When I remove the tool "test/nonexistent"
Then the removal should fail
# ---- Name Collision Detection ----
Scenario: Duplicate registration raises ToolError
Given a tool registry
And a registered tool spec named "test/duplicate"
When I try to register a duplicate tool "test/duplicate"
Then a ToolError should be raised with type "RegistrationError"
# ---- Capability Flag Validation ----
Scenario: Tool spec with read-only capability
Given a tool spec named "test/reader" with read_only capability
Then the tool spec capabilities read_only should be True
And the tool spec capabilities writes should be False
Scenario: Tool spec with write capability
Given a tool spec named "test/writer" with writes capability
Then the tool spec capabilities writes should be True
# ---- Tool Lifecycle Hook Ordering ----
Scenario: Full lifecycle discover activate execute deactivate
Given a tool registry
And a registered tool spec named "test/lifecycle"
And a tool runner for the registry
When I discover tools from the runner
And I activate tool "test/lifecycle"
And I execute tool "test/lifecycle" with inputs {"key": "value"}
And I deactivate tool "test/lifecycle"
Then the lifecycle should complete in order
# ---- Execute With Valid Inputs ----
Scenario: Execute with valid inputs returns success
Given a tool registry
And a registered tool spec named "test/add" with an adder handler
And a tool runner for the registry
When I activate tool "test/add"
And I execute tool "test/add" with inputs {"a": 1, "b": 2}
Then the tool result should be successful
And the tool result output should contain key "sum"
And the tool result duration_ms should be non-negative
# ---- Execute With Handler Failure ----
Scenario: Execute with handler failure returns failure result
Given a tool registry
And a registered tool spec named "test/fail" with a failing handler
And a tool runner for the registry
When I execute tool "test/fail" with inputs {}
Then the tool result should not be successful
And the tool result error should not be empty
# ---- Thread-Safe Concurrent Registration ----
Scenario: Concurrent registrations are thread-safe
Given a tool registry
When I concurrently register 50 tools
Then all 50 tools should be in the registry
# ---- JSON-Serialisable IO Validation ----
Scenario: Execute rejects non-JSON-serialisable inputs
Given a tool registry
And a registered tool spec named "test/json-check"
And a tool runner for the registry
When I execute tool "test/json-check" with non-serialisable inputs
Then the tool result should not be successful
And the tool result error should mention "JSON"
Scenario: Execute rejects non-JSON-serialisable outputs
Given a tool registry
And a registered tool spec named "test/bad-output" with a non-serialisable handler
And a tool runner for the registry
When I execute tool "test/bad-output" with inputs {}
Then the tool result should not be successful
And the tool result error should mention "JSON"
# ---- ToolError Exception ----
Scenario: ToolError carries structured context
When I create a ToolError with name "test/err" type "TestError" and details "something broke"
Then the ToolError tool_name should be "test/err"
And the ToolError error_type should be "TestError"
And the ToolError details should be "something broke"
And the ToolError message should contain "TestError"
# ---- ToolResult Model ----
Scenario: ToolResult with success and metadata
When I create a ToolResult with success True and metadata
Then the ToolResult success should be True
And the ToolResult metadata should not be empty
Scenario: ToolResult with failure
When I create a ToolResult with success False and error "handler crashed"
Then the ToolResult success should be False
And the ToolResult error should be "handler crashed"
# ---- Runner Activate Errors ----
Scenario: Activate missing tool raises ToolError
Given a tool registry
And a tool runner for the registry
When I try to activate a missing tool "test/missing"
Then a ToolError should be raised with type "ActivationError"
# ---- Runner Execute Missing Tool ----
Scenario: Execute missing tool raises ToolError
Given a tool registry
And a tool runner for the registry
When I try to execute a missing tool "test/missing" with inputs {}
Then a ToolError should be raised with type "ExecutionError"
# ---- Runner Deactivate ----
Scenario: Deactivate a non-active tool returns False
Given a tool registry
And a tool runner for the registry
When I deactivate tool "test/nonexistent"
Then the deactivation should return False
# ---- Discover With Alternate Registry ----
Scenario: Discover from an alternate registry
Given a tool registry
And a tool runner for the registry
And an alternate registry with 3 tools
When I discover tools from the alternate registry
Then the discovered list should contain 3 tools
# ---- Execute Without Prior Activate ----
Scenario: Execute without prior activate still works via registry lookup
Given a tool registry
And a registered tool spec named "test/no-activate" with an adder handler
And a tool runner for the registry
When I execute tool "test/no-activate" with inputs {"a": 5, "b": 3}
Then the tool result should be successful
# ---- Handler Returns Non-Dict ----
Scenario: Handler returning non-dict is wrapped in result dict
Given a tool registry
And a registered tool spec named "test/scalar" with a scalar handler
And a tool runner for the registry
When I execute tool "test/scalar" with inputs {}
Then the tool result should be successful
And the tool result output should contain key "result"
# ---- List Tools With tool_type Filter ----
Scenario: List tools with tool_type filter
Given a tool registry
And a registered tool spec named "test/filtered"
When I list tools with tool_type "tool"
Then the tool list should contain 1 tools