Convert a :class:~teff.tool.Tool to an OpenAI-style function schema.
Uses the tool's schema attribute when set (e.g. by MCP tools);
otherwise infers parameters from the run/arun signature.
Nested type hints (list[dict], dict[str, str], dataclasses,
TypedDict) expand to nested JSON Schemas.
Source code in teff/harness/schema.py
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 | def tool_to_schema(tool: Tool) -> dict:
"""Convert a :class:`~teff.tool.Tool` to an OpenAI-style function schema.
Uses the tool's ``schema`` attribute when set (e.g. by MCP tools);
otherwise infers ``parameters`` from the ``run``/``arun`` signature.
Nested type hints (``list[dict]``, ``dict[str, str]``, dataclasses,
``TypedDict``) expand to nested JSON Schemas.
"""
provider_schema = tool.schema
if isinstance(provider_schema, dict):
return {
"type": "function",
"function": {
"name": tool.name,
"description": tool.description or "",
"parameters": provider_schema,
},
}
run_method = tool.run
if type(tool).run is Tool.run and type(tool).arun is not Tool.arun:
run_method = tool.arun
sig = inspect.signature(run_method)
try:
hints = typing.get_type_hints(run_method)
except Exception:
hints = {}
properties: dict = {}
required: list[str] = []
for pname, param in sig.parameters.items():
if pname in ("self", "kwargs", "args"):
continue
if pname.startswith("__"):
# Internal runtime kwargs (e.g. ``__state__``/``__ctx__``) injected
# by the executor — never exposed to the model as call arguments.
continue
prop: dict = _py_type_to_schema(hints.get(pname, str))
if param.default is not inspect.Parameter.empty:
if param.default is not None:
prop["default"] = param.default
else:
required.append(pname)
properties[pname] = prop
return {
"type": "function",
"function": {
"name": tool.name,
"description": tool.description or "",
"parameters": {
"type": "object",
"properties": properties,
"required": required,
},
},
}
|