{"_id":"@brngdsn/swarm-js","name":"@brngdsn/swarm-js","dist-tags":{"latest":"0.2.0"},"versions":{"0.2.0":{"name":"@brngdsn/swarm-js","version":"0.2.0","description":"A lightweight, stateless multi-agent orchestration framework for Node.js","main":"src/index.js","type":"module","scripts":{"test":"echo \"No tests configured\""},"keywords":["ai agents","openai","javascript"],"author":{"name":"brn.gdsn@gmail.com"},"license":"MIT","dependencies":{"chalk":"^5.4.1","dotenv":"^16.4.7","openai":"latest","ora":"^8.1.1"},"bugs":{"url":"https://github.com/brngdsn/swarm-js/issues"},"homepage":"https://github.com/brngdsn/swarm-js#readme","repository":{"type":"git","url":"git+https://github.com/brngdsn/swarm-js.git"},"engines":{"node":">=20.8.0"},"_id":"@brngdsn/swarm-js@0.2.0","gitHead":"13164f29f2c995642ff72df64e92e0ae90785f14","_nodeVersion":"20.8.0","_npmVersion":"10.1.0","dist":{"integrity":"sha512-OXVttr1KB+wWbwOW6VU1ybRh7uMhhsgAfxtwc5el2estTYKko0dhGm/0BeCSKTLYIxdHrXgDEzClCono0Jy2Uw==","shasum":"e0a2dd6f74ebf14341f040d92488049c5e54aa12","tarball":"https://registry.npmjs.org/@brngdsn/swarm-js/-/swarm-js-0.2.0.tgz","fileCount":11,"unpackedSize":1259405,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICqq9zJdQm44NXOGopstXo9UmZ7OqlCPptuLruDbhUmdAiBYyrNSegZzwVw8F6wk9L7HHugwwR2cMjdNT1+cEt7LEw=="}]},"_npmUser":{"name":"brngdsn","email":"brn.gdsn@gmail.com"},"directories":{},"maintainers":[{"name":"brngdsn","email":"brn.gdsn@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/swarm-js_0.2.0_1737663119760_0.9494371546249196"},"_hasShrinkwrap":false}},"time":{"created":"2025-01-23T20:11:59.680Z","0.2.0":"2025-01-23T20:12:00.004Z","modified":"2025-01-23T20:12:00.278Z"},"maintainers":[{"name":"brngdsn","email":"brn.gdsn@gmail.com"}],"description":"A lightweight, stateless multi-agent orchestration framework for Node.js","homepage":"https://github.com/brngdsn/swarm-js#readme","keywords":["ai agents","openai","javascript"],"repository":{"type":"git","url":"git+https://github.com/brngdsn/swarm-js.git"},"author":{"name":"brn.gdsn@gmail.com"},"bugs":{"url":"https://github.com/brngdsn/swarm-js/issues"},"license":"MIT","readme":"# SwarmJS\r\n\r\n![SwarmJS Logo](./assets/swarm-js-logo.png)\r\n\r\n**Swarm JS** is an experimental framework for orchestrating multiple AI \"agents\" that can transfer control to each other and call functions (or \"tools\") in a chat-based workflow. It uses the [OpenAI Node.js library][openai-npm], along with a few utilities, to facilitate multi-step reasoning and delegation across different agents with specialized instructions.\r\n\r\n![SwarmJS Logo](./assets/swarm-js.gif)\r\n\r\n## Table of Contents\r\n\r\n- [Features](#features)\r\n- [Installation](#installation)\r\n- [Usage](#usage)\r\n  - [1. Creating Agents](#1-creating-agents)\r\n  - [2. Defining Tools](#2-defining-tools)\r\n  - [3. Running the Swarm](#3-running-the-swarm)\r\n  - [4. Example Usage](#4-example-usage)\r\n- [API Reference](#api-reference)\r\n  - [`SwarmJS` Class](#swarmjs-class)\r\n  - [`Agent` Class](#agent-class)\r\n  - [`Response` Class](#response-class)\r\n  - [`run_demo_loop` Function](#run_demo_loop-function)\r\n- [Environment Variables](#environment-variables)\r\n- [How It Works](#how-it-works)\r\n- [Contributing](#contributing)\r\n- [License](#license)\r\n\r\n---\r\n\r\n## Features\r\n\r\n- **Multi-agent orchestration**: Define multiple agents, each with its own role, instructions, and tools.\r\n- **Tool calling**: Agents can call functions you provide (\"tools\") to perform specific tasks such as database lookups, refunds, or any custom logic.\r\n- **Agent transfer**: Agents can return another agent to \"transfer control\" of the conversation.\r\n- **Automatic parameter extraction**: Tools can be annotated for their parameters, which helps create function calling schemas automatically.\r\n- **Interactive spinner and logs**: Uses [ora][ora-npm] and [chalk][chalk-npm] to display helpful CLI feedback.\r\n\r\n---\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install swarm-js\r\n```\r\n\r\n> **Note**: Swarm JS depends on the [OpenAI Node.js library][openai-npm], which is installed as a dependency. Make sure to have a valid OpenAI API key to use its features.\r\n\r\n---\r\n\r\n## Usage\r\n\r\nBelow is a quick overview of how to set up and use Swarm JS in your Node.js or TypeScript project.\r\n\r\n### 1. Creating Agents\r\n\r\nAn **Agent** represents an AI persona or \"role\" in your application. You can create as many agents as you like, each with its own `name`, `model`, `instructions`, and `tools`.\r\n\r\n```js\r\nimport { Agent } from 'swarm-js';\r\n\r\nconst triage_agent = new Agent({\r\n  name: 'Triage Agent',\r\n  model: 'gpt-4o-mini',\r\n  instructions: `\r\n    Analyze the user's request and determine the appropriate course of action.\r\n    - If the request involves a refund, first obtain the item ID from the Inventory Agent.\r\n    - After obtaining the item ID, transfer to the Refunds Agent to process the refund.\r\n    - Ensure that all necessary information is gathered before processing.\r\n  `,\r\n  tools: [] // will add tools later\r\n});\r\n```\r\n\r\n### 2. Defining Tools\r\n\r\n\"Tools\" are just JavaScript functions, but you can annotate them with a `.doc` property to describe what they do. **Swarm JS** automatically converts each tool into a JSON schema for function calling in the OpenAI API.  \r\n\r\nA tool can optionally transfer conversation control by returning another `Agent` instance.\r\n\r\n```js\r\nfunction look_up_item(search_query) {\r\n  // Use search_query to find an item\r\n  return \"item_00000\";\r\n}\r\nlook_up_item.doc = `Use to find an item ID. Search query can be a description or keywords.`;\r\n\r\nfunction execute_refund(item_id, reason = \"not provided\") {\r\n  // Issue refund logic\r\n  console.log(`Refunding ${item_id}. Reason: ${reason}`);\r\n  return \"Success\";\r\n}\r\nexecute_refund.doc = `Use to issue a refund by item ID.`;\r\n\r\nfunction transfer_back_to_triage() {\r\n  // Returns an Agent instance to transfer control back to the triage agent\r\n  return triage_agent;\r\n}\r\ntransfer_back_to_triage.doc = `\r\n  Call this function if a user is asking about a topic \r\n  that is not handled by the current agent.\r\n`;\r\n\r\n// Attach these tools to agents\r\ntriage_agent.tools = [ /* ...some tools... */ ];\r\n```\r\n\r\n### 3. Running the Swarm\r\n\r\n`SwarmJS` manages the conversation loop with OpenAI. It:\r\n1. Sends messages to OpenAI.\r\n2. Receives potential function calls from the model (i.e., \"tool calls\").\r\n3. Executes those calls (if applicable).\r\n4. Allows agents to transfer to different agents.\r\n\r\n```js\r\nimport { SwarmJS } from 'swarm-js';\r\n\r\nconst swarm = new SwarmJS(); \r\n\r\nasync function runChatFlow() {\r\n  const messages = [{ role: 'user', content: 'I would like to return a Christmas tree.' }];\r\n  const response = await swarm.run(\r\n    triage_agent, // the initial agent\r\n    messages     // the conversation so far\r\n  );\r\n  console.log(response);\r\n}\r\n\r\nrunChatFlow();\r\n```\r\n\r\n### 4. Example Usage\r\n\r\nBelow is a more complete example with three agents (`Triage Agent`, `Inventory Agent`, and `Refunds Agent`) and the relevant tools:\r\n\r\n```js\r\nimport { Agent, SwarmJS } from 'swarm-js';\r\n\r\n// Define your agents\r\nconst triage_agent = new Agent({\r\n  name: 'Triage Agent',\r\n  model: 'gpt-4o-mini',\r\n  instructions: `\r\n    Analyze the user's request and determine the appropriate course of action.\r\n    - If the request involves a refund, first obtain the item ID from the Inventory Agent.\r\n    - After obtaining the item ID, transfer to the Refunds Agent to process the refund.\r\n    - Ensure that all necessary information is gathered before processing.\r\n  `,\r\n  tools: [] // we'll populate this later\r\n});\r\n\r\nconst inventory_agent = new Agent({\r\n  name: 'Inventory Agent',\r\n  model: 'gpt-4o-mini',\r\n  instructions: `\r\n    Assist with finding item IDs for refunding items, then transfer back to triage.\r\n  `,\r\n  tools: []\r\n});\r\n\r\nconst refunds_agent = new Agent({\r\n  name: 'Refunds Agent',\r\n  model: 'gpt-4o-mini',\r\n  instructions: `\r\n    Assist with issuing refunds using an item ID, then transfer back to triage.\r\n  `,\r\n  tools: []\r\n});\r\n\r\n// Define your tools\r\nfunction look_up_item(search_query) {\r\n  return \"item_00000\";\r\n}\r\nlook_up_item.doc = `Use to find an item ID. Search query can be a description or keywords.`;\r\n\r\nfunction execute_refund(item_id, reason = \"not provided\") {\r\n  console.log(`Refunding ${item_id}. Reason: ${reason}`);\r\n  return \"Success\";\r\n}\r\nexecute_refund.doc = `Use to issue a refund by item ID.`;\r\n\r\n// Transfers\r\nfunction transfer_back_to_triage() {\r\n  return triage_agent;\r\n}\r\ntransfer_back_to_triage.doc = `Transfers the conversation back to Triage Agent.`;\r\n\r\nfunction transfer_to_inventory_agent() {\r\n  return inventory_agent;\r\n}\r\ntransfer_to_inventory_agent.doc = `Transfers the conversation to Inventory Agent.`;\r\n\r\nfunction transfer_to_refunds_agent() {\r\n  return refunds_agent;\r\n}\r\ntransfer_to_refunds_agent.doc = `Transfers the conversation to Refunds Agent.`;\r\n\r\n// Attach the tools\r\ntriage_agent.tools = [ transfer_to_inventory_agent, transfer_to_refunds_agent ];\r\ninventory_agent.tools = [ look_up_item, transfer_back_to_triage ];\r\nrefunds_agent.tools = [ execute_refund, transfer_back_to_triage ];\r\n\r\n// Run the swarm\r\n(async () => {\r\n  const swarm = new SwarmJS();\r\n  const initial_messages = [\r\n    {\r\n      role: 'user',\r\n      content: 'I would like to return a Christmas tree.'\r\n    }\r\n  ];\r\n  \r\n  const response = await swarm.run(triage_agent, initial_messages);\r\n  console.log(response.messages);\r\n})();\r\n```\r\n\r\n---\r\n\r\n## API Reference\r\n\r\n### `SwarmJS` Class\r\n\r\n```ts\r\nconstructor({ openai }?: { openai?: OpenAI });\r\n```\r\n\r\n- Creates a new instance of the **SwarmJS** orchestrator.  \r\n- Optionally accepts an `OpenAI` client instance. If not provided, it defaults to using the `OPENAI_API_KEY` environment variable.\r\n\r\n#### `run(agent: Agent, messages: ChatCompletionMessage[]): Promise<Response>`\r\n\r\n- Begins a conversation loop with the provided `agent` and list of `messages`.\r\n- In each step, it sends the conversation to OpenAI, checks for any tool calls, executes them, and updates the conversation accordingly.\r\n- Returns a `Response` object upon completion.\r\n\r\n---\r\n\r\n### `Agent` Class\r\n\r\n```ts\r\nclass Agent {\r\n  constructor({\r\n    name?: string;\r\n    model?: string;\r\n    instructions?: string;\r\n    tools?: Function[];\r\n  });\r\n}\r\n```\r\n\r\n- Represents an AI persona, with:\r\n  - **name**: A friendly identifier for this agent.\r\n  - **model**: The name of the LLM to use (e.g., `\"gpt-4o-mini\"`).\r\n  - **instructions**: System instructions or a \"persona\" description for the agent.\r\n  - **tools**: An array of functions that can be called by the agent.\r\n\r\n#### `Agent.is_agent(obj: any): boolean`\r\n\r\n- Returns `true` if `obj` is an instance of `Agent`.\r\n\r\n---\r\n\r\n### `Response` Class\r\n\r\n```ts\r\nclass Response {\r\n  agent: Agent;\r\n  messages: ChatCompletionMessage[];\r\n  constructor({ agent, messages }?: { agent?: Agent; messages?: ChatCompletionMessage[] });\r\n}\r\n```\r\n\r\n- A simple response wrapper that includes:\r\n  - **agent**: The final agent context after all transfers.\r\n  - **messages**: The entire chat history.\r\n\r\n---\r\n\r\n### `run_demo_loop` Function\r\n\r\n```ts\r\nasync function run_demo_loop(initial_agent: Agent): Promise<void>;\r\n```\r\n\r\n- An example/demo function that initializes a `SwarmJS` instance, runs a short conversation (with a single user request), and writes the resulting messages to a file (`eg-run.md`).\r\n- This demonstrates how to use **SwarmJS** in a simple loop.\r\n\r\n---\r\n\r\n## Environment Variables\r\n\r\n- **`OPENAI_API_KEY`**: If you do not provide a custom OpenAI client to the `SwarmJS` constructor, it will look for this environment variable to authenticate with the [OpenAI API][openai-api].\r\n\r\n---\r\n\r\n## How It Works\r\n\r\n1. **Agent & Tools**: You define one or more agents (via the `Agent` class), each containing:\r\n   - A unique name\r\n   - Custom instructions\r\n   - A list of \"tool\" functions, each annotated with `.doc` for usage hints\r\n\r\n2. **Parameter Extraction**: Swarm JS automatically converts these tools into JSON schemas that the OpenAI function-calling API can understand.  \r\n   - It does this by analyzing the function signature and any default parameter values or docstrings.\r\n\r\n3. **Conversation Loop**:\r\n   - The user messages (along with system instructions) are sent to OpenAI.\r\n   - OpenAI may request to call a tool function by name, with arguments derived from the conversation.\r\n   - Swarm JS executes the tool function and appends the result to the conversation.\r\n   - The conversation continues until no more tool calls are requested.\r\n\r\n4. **Agent Transfer**: If a tool returns another `Agent` instance, the conversation \"transfers\" to that agent. Subsequent steps in the conversation use the new agent's instructions and tools.\r\n\r\n---\r\n\r\n## Contributing\r\n\r\nContributions, suggestions, and feedback are welcome! You can:\r\n- Fork the repository\r\n- Create a feature branch\r\n- Submit a pull request\r\n\r\n---\r\n\r\n## License\r\n\r\nMIT License. See [LICENSE](./LICENSE) for details.\r\n\r\n---\r\n\r\n[openai-npm]: https://www.npmjs.com/package/openai\r\n[openai-api]: https://platform.openai.com/docs/api-reference\r\n[ora-npm]: https://www.npmjs.com/package/ora\r\n[chalk-npm]: https://www.npmjs.com/package/chalk\r\n","readmeFilename":"README.md"}