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
- 55/100 · Major gaps
At a glance
- Works with
- Platform-specificOpenAI API
- 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. - Main limitation
- Its documented execution model is tied to the OpenAI Assistants API, with no documented alternative-provider adapter.
- Source review
- 55/100 · Major gaps 1 safety controls not found
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 | Stars | Updated | Language | Full support on |
|---|---|---|---|---|---|
| Experts.js This agent | 55 · Major gaps | ★ 1.1k | 2y ago | JavaScript | OpenAI API |
| Hello-Agents | 54 · Major gaps | ★ 81k | 1d ago | Python | OpenAI API |
| Dynamiq Agent Orchestration | 61 · Some gaps | ★ 1.1k | 1d ago | Python | OpenAI API |
| LangGraph Multi-Agent Swarm | 51 · Major gaps | ★ 1.6k | 4d ago | Python | OpenAI API |
How does FollowAgents rate this agent?
Why each dimension lost points
Evidence shows: MIT license, author Ken Collins, but publisher unverified. No malicious behavior found, but external API calls (OpenAI, postimages) and tests require API keys. No user confirmation mechanism, limited data flow transparency, sensitive data handling unclear. Dependencies include openai and eventemitter2, but no security audit. External effects include creating and deleting OpenAI resources, but no rollback mechanism. Source attribution clear, but publisher identity unknown. Deductions: lack of user confirmation, insufficient data flow transparency, unclear sensitive data handling, un-audited dependency security, no rollback for external effects.
Evidence shows: README and code examples consistent, test suite exists, but tests depend on external APIs and may be flaky. Dependencies listed in package.json, but no version locking. Failure messages not detailed. Deductions: tests depend on external services, failure messages insufficient.
Evidence shows: README provides multiple use cases, including product catalog, streaming, image messages, vector store. Capability boundaries documented but not explicit. Trigger precision via tool names and descriptions, but not detailed. Environment fit supports ES6 and CommonJS, but no browser support. Deductions: capability boundaries unclear, trigger precision relies on model.
Evidence shows: README well-structured, installation simple, naming stable, examples abundant, but known limitations not explicit. License MIT, version present, but changelog missing. Maintenance responsibility by author, but not explicit. Deductions: known limitations not listed, changelog missing.
Evidence shows: Output usability high, multiple output modes. Marginal value high, simplifies Assistants API. Cost-benefit reasonable, but no performance data. Deductions: cost-benefit not quantified.
Evidence shows: README claims consistent with code, test suite provides partial verification. But no independent verification. Fact-inference separation good. Deductions: cross-source corroboration insufficient.
- Not found in source: confirmation before actingTurn on (or add) a confirmation step before it acts, and try it in a sandbox or test environment before real data.
- Publisher identity unverified; assess risk before use.
- Tests depend on external APIs and keys, may be flaky and pose security risks.
- No user confirmation mechanism; tool calls may execute automatically.
- Dependencies not security-audited; check for vulnerabilities.
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.