Skip to main content

LangGraph middleware for binding client-declared tool stubs and routing client tool calls to END so the browser executes them.

Project description

threadplane-client-tools

LangGraph middleware for binding client-declared tool stubs and routing client tool calls to END so the browser executes them.

How it works

When a browser client sends a tool catalog ({name, description, parameters} dicts) along with a run request, the graph can expose those tools to the LLM and route their calls back to the browser instead of executing them server-side. The browser then executes the call and re-runs the graph with a ToolMessage carrying the result.

The catalog is read from state["tools"], falling back to state["client_tools"] if tools is absent.

Installation

pip install threadplane-client-tools

Usage

from langgraph.graph import END, StateGraph
from threadplane.client_tools import bind_client_tools, route_after_agent

# Server-side tools your graph owns
SERVER_TOOLS = [search_tool, calculator_tool]
base_llm = ChatOpenAI(model="gpt-4o")

def agent_node(state):
    # bind_client_tools must be called per-run inside the node because
    # the client catalog arrives in state and may differ between runs.
    llm = bind_client_tools(base_llm, SERVER_TOOLS, state)
    response = llm.invoke(state["messages"])
    return {"messages": [response]}

def router(state):
    # Returns "tools" for server tool calls, "__end__" otherwise.
    # Map "__end__" to LangGraph's END in add_conditional_edges.
    return route_after_agent(state, [t.name for t in SERVER_TOOLS])

graph = StateGraph(...)
graph.add_node("agent", agent_node)
graph.add_node("tools", ToolNode(SERVER_TOOLS))
graph.add_conditional_edges("agent", router, {"tools": "tools", "__end__": END})

What happens with a client tool call

  1. The LLM emits a tool call whose name matches a client-declared tool.
  2. route_after_agent returns "__end__" — the graph run ends.
  3. The browser receives the partial output, executes the tool locally, and re-runs the graph with a ToolMessage containing the result.
  4. The LLM continues from there as if it had called a server tool.

Lower-level helpers

from threadplane.client_tools import (
    client_tool_specs,   # → list of OpenAI function-tool dicts
    client_tool_names,   # → set[str] of client tool names
    has_client_tool_call,  # → bool
    has_server_tool_call,  # → bool
    last_message,          # → last message from state["messages"]
)

Development

uv venv
uv pip install -e '.[test]'
uv run pytest -q

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

threadplane_client_tools-0.0.1.tar.gz (95.5 kB view details)

Uploaded Source

Built Distribution

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

threadplane_client_tools-0.0.1-py3-none-any.whl (4.3 kB view details)

Uploaded Python 3

File details

Details for the file threadplane_client_tools-0.0.1.tar.gz.

File metadata

  • Download URL: threadplane_client_tools-0.0.1.tar.gz
  • Upload date:
  • Size: 95.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for threadplane_client_tools-0.0.1.tar.gz
Algorithm Hash digest
SHA256 9fbc7aab0167145f56f5caddb667ad56df9bd847b681d80243085d2c6f1a8ac3
MD5 aa0e33ac81b7cfcc65129d9946fe5846
BLAKE2b-256 2b6d142e2686892859dd9fae080a08e0173f4adad0e25566de8ce3bcf569e844

See more details on using hashes here.

File details

Details for the file threadplane_client_tools-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: threadplane_client_tools-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 4.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for threadplane_client_tools-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0a898f4bd89101305fe0f9fd3e254902f0ddaadd41ab40a25bd4980c499bf3b8
MD5 b7007c33fe41f2f1469f5e5a716a81ef
BLAKE2b-256 5bb76ca34dd8d642477e8558f1f9d2616ebe0b8189c44807af7f5e369867b1dc

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