Skip to main content

LLM function calling on steroids using Abstract Syntax Trees.

Project description

🌲 treelang

PyPI - Version PyPI Downloads License: MIT

Turn your toolboxes into executable Abstract Syntax Trees (ASTs) that Large Language Models can plan in a single shot. treelang lets you express arbitrarily complex workflows, keep sensitive values out of the LLM, and reuse the resulting programs as shareable, cacheable trees.

Highlights

  • One LLM call, full plan – generate an AST for a complete solution without the expensive function-call loop.
  • Complex workflows – conditionals, higher-order functions (map, filter, reduce), and nested tool invocations all live in one tree.
  • Secure + green – the LLM never sees tool results; you evaluate nodes locally while controlling cost and compliance.
  • Model Context Protocol native – ships with an MCP client provider but can work with any tool registry through the ToolProvider abstraction.
  • Composable outputs – turn ASTs into callable tools (AST.tool) or serialize/describe them for sharing, caching, or review.

What you can build

  • Enterprise copilots that must orchestrate dozens of tools with branching logic.
  • Automations that need to fan out over datasets (e.g., score/map/filter large collections asynchronously).
  • Reusable skills: persist an AST, describe it with EvalResponse.describe(), and redeploy it as a tool on your MCP server.
  • LLM evaluation loops: ask for the tree (EvalType.TREE) to inspect reasoning before execution, or walk it immediately for answers.

Quick start

Requirements

  • Python 3.12+
  • An OpenAI API key (OPENAI_API_KEY) and optional OPENAI_MODEL override (defaults to gpt-4o-2024-11-20)
  • A source of tools: an MCP server, or your own provider implementing treelang.ai.provider.ToolProvider

Install

pip install treelang

Wire up tools (MCP)

import asyncio
from contextlib import AsyncExitStack

from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client

from treelang.ai.arborist import EvalType, OpenAIArborist
from treelang.ai.provider import MCPToolProvider


async def build_arborist(stack: AsyncExitStack) -> OpenAIArborist:
    try:
        await stack.__aenter__()
        # Connect to a streamable HTTP server
        read_stream, write_stream, _ = await stack.enter_async_context(
            streamable_http_client("http://localhost:8000/mcp")
        )

        # Create a session using the client streams
        session = await stack.enter_async_context(
            ClientSession(read_stream, write_stream)
        )

        # Initialize the connection
        await session.initialize()

        # Create the Arborist
        provider = MCPToolProvider(session)
        arborist = OpenAIArborist(provider=provider, model="gpt-4o")

        return arborist

    except Exception:
        print ("Error building the Arborist")
        await stack.aclose()
        raise

Ask a question (MCP)

async def run():
    stack = AsyncExitStack()
    arborist = await build_arborist(stack)

    response = await arborist.eval(
        query="Compare next weekend flights BOS➜SFO and summarize the cheapest option.",
        type=EvalType.WALK,  # change to EvalType.TREE to inspect the JSON AST instead
    )
    print(response.content)  # fully-evaluated tool output
    if (stack):
        await stack.aclose()

if __name__ == "__main__":
    asyncio.run(run())

Use response.jsontree with AST.parse() or AST.repr() if you want to log, cache, or transform the raw tree.

Tree-first workflow

  1. GenerateOpenAIArborist assembles an AST using your available tools.
  2. Inspect – represent the tree as JSON, describe it with EvalResponse.describe(), or pretty-print it using AST.repr().
  3. EvaluateAST.eval(tree, provider) asynchronously executes every node; the LLM never sees intermediate values.
  4. Packageawait AST.tool(tree, provider) turns a tree into a callable tool so you can add it back to your MCP server.

Architecture at a glance

  • Arborist (treelang/ai/arborist.py) – orchestrates LLM calls, maintains history via the optional Memory interface, and decides whether to return ASTs or walked results.
  • Tool providers (treelang/ai/provider.py) – abstract how tools are discovered/invoked. We ship an MCP client implementation and a template for custom providers.
  • Selectors (treelang/ai/selector.py) – plug in your own tool filtering logic; AllToolsSelector ships by default.
  • Trees (treelang/trees/tree.py) – immutable node classes plus helpers such as async traversal, repr generation, and turning trees into callable tools.

Resources & examples

  • Cookbook notebooks (cookbook/) walk through building trees, call patterns, and evaluation strategies.
  • Evaluation harness (evaluation/eval.py) stress-tests tree generation using curated toolsets and questions; great for regression testing.
  • Unit tests (tests/) cover the AST core and are a good reference for expected behavior when extending nodes.

Contributing & local development

We actively welcome contributions—see CONTRIBUTING.md for the full workflow.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

treelang-0.9.0.tar.gz (18.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

treelang-0.9.0-py3-none-any.whl (19.9 kB view details)

Uploaded Python 3

File details

Details for the file treelang-0.9.0.tar.gz.

File metadata

  • Download URL: treelang-0.9.0.tar.gz
  • Upload date:
  • Size: 18.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.12.11 Linux/6.9.3-76060903-generic

File hashes

Hashes for treelang-0.9.0.tar.gz
Algorithm Hash digest
SHA256 241418d44b689b44f42f4518d23d6e177c089a4b45c9a537bca0968b85f0aaf2
MD5 9801b6c813600dbf63cc61bfe757a3a1
BLAKE2b-256 8c8a071a1d5a00ded69e13bdff91966eeb75bd6c22c0be85dd4a71384884cd26

See more details on using hashes here.

File details

Details for the file treelang-0.9.0-py3-none-any.whl.

File metadata

  • Download URL: treelang-0.9.0-py3-none-any.whl
  • Upload date:
  • Size: 19.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.12.11 Linux/6.9.3-76060903-generic

File hashes

Hashes for treelang-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fd8127feaf43aade3238f0a9beada9152037db65537632428ab76118baa38fa8
MD5 3aa965d5df48a268e8361b3ce1791087
BLAKE2b-256 c9932032a699b24ad545cc02828e589aa2f483ffb58d0fe5609f83377ec8073b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page