@@ -65,3 +65,76 @@ def test_model_total_entry_still_in_core(self):
6565 from autoskillit .core .types ._type_results import ModelTotalEntry
6666
6767 assert "model" in ModelTotalEntry .__required_keys__
68+
69+
70+ class TestToolFailureEnvelope :
71+ """Verify ToolFailureEnvelope TypedDict and factory helpers."""
72+
73+ def test_tool_failure_envelope_importable (self ):
74+ from autoskillit .server .tools ._types import ToolFailureEnvelope
75+
76+ assert "success" in ToolFailureEnvelope .__required_keys__
77+
78+ def test_tool_failure_envelope_required_keys (self ):
79+ from autoskillit .server .tools ._types import ToolFailureEnvelope
80+
81+ expected = {"success" , "error" , "stage" , "retriable" }
82+ assert expected <= ToolFailureEnvelope .__required_keys__
83+
84+ def test_tool_failure_envelope_optional_keys (self ):
85+ from autoskillit .server .tools ._types import ToolFailureEnvelope
86+
87+ assert "user_visible_message" in ToolFailureEnvelope .__optional_keys__
88+
89+ def test_tool_failure_envelope_success_type (self ):
90+ import typing
91+
92+ from autoskillit .server .tools ._types import ToolFailureEnvelope
93+
94+ hints = typing .get_type_hints (ToolFailureEnvelope )
95+ assert typing .get_args (hints ["success" ]) == (False ,)
96+
97+ def test_server_failure_envelope_factory (self ):
98+ from autoskillit .server .tools ._types import server_failure_envelope
99+
100+ result = server_failure_envelope (ValueError ("boom" ), "init" )
101+ assert result ["success" ] is False
102+ assert result ["retriable" ] is True
103+ assert result ["stage" ] == "init"
104+ assert "ValueError" in result ["error" ]
105+ assert "boom" in result ["error" ]
106+
107+ def test_input_failure_envelope_factory (self ):
108+ from autoskillit .server .tools ._types import input_failure_envelope
109+
110+ result = input_failure_envelope ("bad input" , "validate" )
111+ assert result ["success" ] is False
112+ assert result ["retriable" ] is False
113+ assert result ["stage" ] == "validate"
114+ assert result ["error" ] == "bad input"
115+
116+ def test_server_failure_envelope_user_visible_message (self ):
117+ from autoskillit .server .tools ._types import server_failure_envelope
118+
119+ result = server_failure_envelope (RuntimeError ("oops" ), "startup" )
120+ assert "user_visible_message" in result
121+ assert len (result ["user_visible_message" ]) > 0
122+
123+ def test_tool_failure_envelope_in_all (self ):
124+ from autoskillit .server .tools ._types import __all__ as types_all
125+
126+ assert "ToolFailureEnvelope" in types_all
127+ assert "server_failure_envelope" in types_all
128+ assert "input_failure_envelope" in types_all
129+
130+ def test_tool_failure_envelope_distinct_from_kitchen_envelope (self ):
131+ from autoskillit .server .tools ._types import ToolFailureEnvelope
132+ from autoskillit .server .tools .tools_kitchen import (
133+ _kitchen_failure_envelope ,
134+ )
135+
136+ assert "retriable" in ToolFailureEnvelope .__required_keys__
137+ all_keys = ToolFailureEnvelope .__required_keys__ | ToolFailureEnvelope .__optional_keys__
138+ assert "kitchen" not in all_keys
139+ result = _kitchen_failure_envelope (ValueError ("x" ), "test" )
140+ assert isinstance (result , str )
0 commit comments