Experts.js
Build OpenAI Assistant workflows where specialized assistants operate as callable tools.
- Source repo
- metaskills/experts
- Stars
- ★ 1.1k
- Last updated
- 2y ago
- License
- MIT
- Primary language
- JavaScript
- FA score
- 46/100 · Major gaps
At a glance
- How it runs
- Works with
- Platform-specificOpenAI API
- Cost
- Free software; you pay for model usage
- Setup effort
- Low · running in minutes
- You'll need
- Typical use
- A Node.js team building an internal assistant that wants a concise
ask()interface instead of directly managing OpenAI Run objects. - Not a fit if
- Teams avoiding OpenAI vendor lock-in; no alternative provider adapter is documented
- Developers unwilling to manage an OpenAI API key and pay-per-use costs
- Source review
- 46/100 · Major gaps
What does this agent do, and when should you use it?
Experts.js is a JavaScript library that wraps the OpenAI Assistants API around three primary objects: Assistant, Tool, and Thread. An application creates a Thread and an Assistant, then uses ask() to send a message and receive output while the library manages Runs and Run Steps. Tool extends Assistant, allowing a parent Assistant or another Tool to invoke a specialized assistant through function-tool definitions. Tools may be LLM-backed or implement their own ask() behavior with llm set to false. Streaming lifecycle events expose text, image-file, tool-call, and run-step activity. For production, an Assistant or Tool can be initialized with an existing asst_ id so the same remote assistant is reused and local configuration can update it.
The application imports Assistant, Tool, and Thread from experts, creates a context with Thread.create(), creates an assistant with Assistant.create(), and calls assistant.ask(message, threadID). ask() accepts either a string or a native OpenAI message object and handles the Run lifecycle. Event handlers such as on("textDelta") receive streaming text, while other documented events surface tool calls, image files, and completed run steps. A parent adds an assistant-backed tool through addAssistantTool; the child Tool's response is submitted as the parent tool output. For nested LLM-backed tools, the library finds or creates separate child threads and stores the parent-to-child relationship in OpenAI thread metadata.
- A Node.js team building an internal assistant that wants a concise
ask()interface instead of directly managing OpenAI Run objects. - An application developer splitting catalog lookup and OpenSearch query generation into specialized Tools called by a company assistant.
- An Express backend that streams assistant response chunks to a client using the
textDeltaevent. - A knowledge-search application configuring
file_searchwithvector_store_idsfor an OpenAI Vector Store. - A multi-assistant workflow that needs separate context threads for child tools to avoid documented thread-locking issues.
How do you install or deploy this agent?
Install with npm install experts, then import Assistant, Tool, and Thread from experts. The documented development setup creates .env.development.local with OPENAI_API_KEY=sk-... and POST_IMAGES_API_KEY=..., followed by ./bin/setup and ./bin/test. A minimal invocation is: const thread = await Thread.create(); const assistant = await Assistant.create(); const output = await assistant.ask("Say hello.", thread.id);.
How do you use this agent?
Pass options such as name, instructions, model, tools, and tool_resources to an Assistant subclass through super(); the documented default model is gpt-4o-mini. Add a specialized tool after super() with this.addAssistantTool(EchoTool). For streaming output, register assistant.on("textDelta", (delta) => process.stdout.write(delta.value)) before calling ask(). In production, supply an existing asst_... id in constructor options; set skipUpdate: true when the remote assistant should not be updated from local configuration.
What are this agent's strengths and limitations?
- Provides a small object model—Assistant, Tool, and Thread—while hiding Run and Run Step management behind
ask(). - Lets assistants serve as reusable function tools, including multi-tier parent and child orchestration.
- Exposes both standard streaming events and post-run async variants for response streaming, tool handling, and usage reporting.
- Supports documented OpenAI tool configuration including function calling,
file_search,code_interpreter, and Vector Store resources.
- Its documented execution model is tied to the OpenAI Assistants API, with no documented alternative-provider adapter.
- Every question requires a thread ID, so a chat application still needs to persist that identifier.
- Function names for Tools must be unique across a parent's complete tool set, creating a naming constraint in larger systems.
- OpenAI server-sent events are documented as not async/await friendly; asynchronous listeners need the library's Async event extensions.
How does this agent compare with similar options?
Compared with direct use of the OpenAI Chat Completions API, Experts.js is organized around Assistants, Threads, Runs, and assistant-backed tools. Unlike Custom GPTs, its documented interface is application code using the OpenAI Assistants API.
Key facts side by side with the most closely related agents.
| Agent | Source review | Form / cost | Stars | Updated | Language | Full support on |
|---|---|---|---|---|---|---|
| Experts.js This agent | 46 · Major gaps | Library / SDKFree + model costs | ★ 1.1k | 2y ago | JavaScript | OpenAI API |
| Hello-Agents | 53 · Major gaps | Web appFree + model costs | ★ 86k | 25d ago | Python | OpenAI API |
| Ouroboros | 77 · Good | Desktop appFree + model costs | ★ 1.6k | today | Python | — |
| Dynamiq Agent Orchestration | 61 · Some gaps | Library / SDKFree + model costs | ★ 1.1k | 3d ago | Python | OpenAI API |
How does FollowAgents rate this agent?
Why each dimension lost points
The documentation says Assistants and Tools call the OpenAI API and use threads, messages, files, and vector stores as context; debug mode exposes API calls and events, so some data flows are visible (2). However, the examples put API keys in a local environment file, and the materials do not explain secret protection, log redaction, permission scope, or confirmation before external operations (least_privilege 1, user_confirmation 1, sensitive_data_handling 1, external_effects 1). Deployment notes say local configuration can overwrite remote configuration and mention skipUpdate, but provide no rollback procedure (1). The README and package metadata identify the project and author, but publisher identity is unverified and maintenance responsibility is not stated (source_attribution 2).
The README, package metadata, and workflow describe the product consistently as an OpenAI Assistants API wrapper, and the core objects and examples mostly align. However, at least one image-message example is missing a comma between object fields, and a factory example omits await despite the documented asynchronous usage; self-consistency is therefore 1. OpenAI SDK dependencies, a Node 18 publishing environment, and installation steps are documented, but the packet provides no lockfile or evidence of dependency supply guarantees (1). The sampled code does not show error classification, user-facing failure messages, or recovery behavior (0).
The material targets JavaScript developers using the OpenAI Assistants API and covers single assistants, nested tools, streaming events, images, vector stores, and an Express scenario (2). It distinguishes LLM and non-LLM tools and explains thread management and unique tool names (2), but tool invocation constraints rely mainly on prompts and descriptions, with no explanation of how to prevent mistaken model calls (1). It documents ES modules and CommonJS, a Node 18 publishing environment, environment variables, and a Dev Container development path (2).
The README is organized around Assistants, Tools, Threads, Runs, Examples, and Deployments; npm installation and development commands are documented (2 each). Naming and object relationships are fairly consistent. The material includes examples and cautions, but no FAQ, and some examples have syntax or async-use doubts (examples_and_faq 2). It notes the async limitations of server-sent events and the behavior of creating new assistants, but its limitations coverage is incomplete (1). LICENSE.md contains the MIT terms (3). package.json provides a version, but the packet contains no changelog content or clear statement of maintenance responsibility, so evidence for history and maintenance path is limited (1 each).
The README supplies usable API examples for events, threads, deployment, and metrics, and describes composing OpenAI Assistants as tools (output_usability 2, marginal_value 2). The product depends on an external OpenAI service and credentials, while nested agents, persistent threads, and tool calls can add cost; the materials give no cost-control or value-assessment guidance, so cost-benefit is 1.
Core feature claims are supported by README examples and API references, with some cross-checks available in package metadata, test files, and CI configuration (claim_traceability 2). Test files contain OpenAI API integration cases and the workflow indicates tests are run, but this does not establish results for this revision, and not all README claims map to implementation or tests in the supplied packet (cross_source_corroboration 1). The text does not systematically distinguish verified facts from goals or promotional assertions; for example, “easiest” is unsupported (fact_inference_separation 1).
- API keys, thread messages, uploaded files, and tool outputs may contain sensitive data; the materials do not describe log redaction or data-retention controls.
- Deployment configuration may overwrite remote Assistant settings; verify IDs and configuration first, as the materials do not describe recovery steps.
- Some examples raise syntax and async-call questions; check the actual API usage before integration.
FAQ
Can it run on Claude or another model provider?
Do I have to create and poll Runs myself?
Assistant.ask() manages Runs. You can still provide Run parameters through constructor run_options or the per-call run option.How do I keep production deployments from creating new assistants?
asst_... id to the Assistant or Tool constructor. Creating without an id is documented to create a new assistant.What does it cost to run?
Thanks — we use this to improve the page.