Skip to content

teff.harness.schema

teff.harness.schema

Tool schema conversion — Python signatures to OpenAI-style function schemas.

Functions:

Name Description
tool_to_schema

Convert a :class:~teff.tool.Tool to an OpenAI-style function schema.

tool_to_schema

tool_to_schema(tool)

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,
            },
        },
    }