OpenAI Assistants API, but you can actually compose them
A thin facade that turns OpenAI's Assistants into reusable, nestable Tools so you can build multi-agent systems without drowning in Run objects.

What it does
Experts.js wraps OpenAI’s Assistants API in three classes — Assistant, Tool, and Thread — and hides the boilerplate of managing Run objects and Run Steps. You create an assistant, call .ask(), and get a string back. The bigger sell is that any Assistant can be registered as a Tool inside another Assistant, so you can build nested “panels of experts” where a parent agent delegates to specialized child agents.
The interesting bit
The framework leans into OpenAI’s function-calling mechanism but flips it: the “function” is itself an LLM-backed Assistant with its own instructions, model, and optional file search. Tools can even be non-LLM — set llm: false and implement ask() yourself to inject raw code or API calls into the agent tree. There’s also an answered() hook that lets a Tool intercept its own LLM output and substitute something else (e.g., run the generated OpenSearch query and return the raw results instead of the query string).
Key highlights
- Hides Run/Run Step lifecycle; streaming events exposed via
.on()with both sync and async variants addAssistantTool()links Assistants as Tools aftersuper()in constructor- Supports
beforeInit()/afterInit()hooks for lazy resource setup and ID persistence - Non-LLM Tools via
llm: falsefor deterministic subroutines - Default model is
gpt-4o-mini; passes through all native OpenAI assistant options
Caveats
- README is truncated mid-example in the sources, so some advanced patterns (full product catalog demo, deployment section) are cut off and unclear
- Tool function names must be globally unique across a parent’s entire tool set — a footgun the docs warn about but don’t automate away
- Tightly coupled to OpenAI’s Assistants API; not a generic agent framework
Verdict
Worth a look if you’re already committed to OpenAI’s Assistants API and want composable, class-based agents without orchestration spaghetti. Skip it if you need provider-agnostic agents or fine-grained control over prompts and token budgets outside OpenAI’s abstraction.