# SwarmJS-Node [![npm version](https://badge.fury.io/js/swarmjs-node.svg)](https://badge.fury.io/js/swarmjs-node) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Build Status](https://github.com/ColeMurray/swarmjs/actions/workflows/ci.yaml/badge.svg)](https://github.com/ColeMurray/swarmjs/actions/workflows/ci.yaml) SwarmJS-Node is a TypeScript library implementation that `o1-mini` generated from OpenAI's Swarm repository. ## ๐Ÿš€ Features - **Agent Management:** Define and manage multiple agents with distinct behaviors and functions. - **Function Calls:** Extend agent capabilities by integrating custom functions. - **Streaming Responses:** Handle and display streaming responses from the Swarm API. - **Debugging:** Enable debug mode for detailed logging and troubleshooting. - **TypeScript Support:** Fully typed library for enhanced developer experience and type safety. - **Environment Variable Management:** Securely handle sensitive information using environment variables. ## ๐Ÿ“ฆ Installation Ensure you have [Node.js](https://nodejs.org/) installed. Then, install `swarmjs-node` via npm: ```bash npm install swarmjs-node ``` Or using [pnpm](https://pnpm.io/): ```bash pnpm add swarmjs-node ``` ## ๐Ÿ“ Prerequisites - **OpenAI API Key:** You'll need an OpenAI API key to interact with the Swarm API. Sign up at [OpenAI](https://platform.openai.com/) if you haven't already. ## ๐Ÿ Quick Start Below is a simple example demonstrating how to initialize the Swarm client, define agents with custom functions, and run a demo loop. ### ๐Ÿ”ง Setup 1. **Clone the Repository:** ```bash git clone https://github.com/ColeMurray/swarmjs.git cd swarmjs ``` 2. **Install Dependencies:** The project uses `pnpm`. If you don't have it installed, you can install it globally: ```bash npm install -g pnpm ``` Then, install the project dependencies: ```bash pnpm install ``` 3. **Build the Project:** Compile the TypeScript code to JavaScript: ```bash pnpm run build ``` 4. **Configure Environment Variables:** Create a `.env` file in the root directory and add your OpenAI API key: ```env OPENAI_API_KEY=your_openai_api_key_here ``` **Note:** Ensure that `.env` is listed in your `.gitignore` to prevent accidental commits of sensitive information. ### ๐Ÿ“‚ Example Usage An example script is provided in the `examples` directory. Here's how to set it up and run it. #### **Example File: `examples/main.ts`** ```typescript // Filename: examples/main.ts import { Agent, AgentFunction } from '../swarm'; import { runDemoLoop } from '../swarm/repl'; import * as dotenv from 'dotenv'; // Load environment variables from .env file dotenv.config(); // Define an addition function const addFunction: AgentFunction = { name: 'add', func: ({ a, b }) => { return (a + b).toString(); }, descriptor: { name: 'add', description: 'Adds two numbers together.', parameters: { a: { type: 'number', required: true, description: 'The first number to add.' }, b: { type: 'number', required: true, description: 'The second number to add.' }, }, }, }; // Define a subtraction function const subFunction: AgentFunction = { name: 'sub', func: ({ a, b }) => { return (a - b).toString(); }, descriptor: { name: 'sub', description: 'Subtracts two numbers.', parameters: { a: { type: 'number', required: true, description: 'The first number.' }, b: { type: 'number', required: true, description: 'The second number.' }, }, }, }; // Define a function to transfer to another agent const transferToHaikuAgent: AgentFunction = { name: 'transfer_to_haiku_agent', func: () => { return agentB; }, descriptor: { name: 'transfer_to_haiku_agent', description: 'Transfers the conversation to the Haiku Agent.', parameters: {}, }, }; // Initialize a Haiku Agent const agentB = new Agent({ name: 'HaikuAgent', model: 'gpt-4o-mini', instructions: 'You only respond in haikus.', }); // Initialize the Helper Agent with functions const agent = new Agent({ name: 'HelperAgent', model: 'gpt-4o-mini', instructions: 'You are a helpful assistant.', functions: [transferToHaikuAgent, addFunction, subFunction], }); // Run the demo loop runDemoLoop(agent, undefined, true, true).catch(error => { console.error('Error running demo loop:', error); }); ``` #### **Running the Example** 1. **Ensure the Project is Built:** ```bash pnpm run build ``` 2. **Run the Example Script:** ```bash pnpm run start:example ``` **Expected Output:** ``` Starting Swarm CLI ๐Ÿ User: Hello HelperAgent: Hello! How can I assist you today? User: Add 5 and 3 HelperAgent: The result of adding 5 and 3 is 8. User: Subtract 10 from 15 HelperAgent: The result of subtracting 10 from 15 is 5. User: Exit Exiting Swarm CLI. ``` *Note: The actual responses may vary based on the implementation and interactions with the OpenAI API.* ## ๐Ÿ“š Detailed Examples For more comprehensive examples and advanced use cases, refer to the [examples](./examples) directory in the repository. You can modify these examples to suit your specific needs or to explore additional functionalities provided by SwarmJS-Node. ## ๐Ÿงฐ Usage Guide ### ๐Ÿ“ฆ Importing the Library ```typescript import { Swarm, Agent, AgentFunction } from 'swarmjs-node'; ``` ### ๐Ÿ›  Defining Agent Functions Agent functions extend the capabilities of your agents by allowing them to perform specific tasks. ```typescript const multiplyFunction: AgentFunction = { name: 'multiply', func: ({ a, b }) => { return (a * b).toString(); }, descriptor: { name: 'multiply', description: 'Multiplies two numbers.', parameters: { a: { type: 'number', required: true, description: 'The first number.' }, b: { type: 'number', required: true, description: 'The second number.' }, }, }, }; ``` ### ๐Ÿƒ Running the Demo Loop The `runDemoLoop` function initializes the interactive CLI for engaging with the Swarm API. ```typescript import { runDemoLoop } from 'swarmjs-node'; const agent = new Agent({ name: 'CalculatorAgent', model: 'gpt-4o-mini', instructions: 'You are a calculator agent that can perform basic arithmetic operations.', functions: [addFunction, subFunction, multiplyFunction], }); runDemoLoop(agent, undefined, true, true).catch(error => { console.error('Error running demo loop:', error); }); ``` ## ๐Ÿงฉ API Reference Comprehensive API documentation is available [here](./docs). This includes detailed descriptions of classes, methods, and interfaces provided by SwarmJS-Node. ## ๐Ÿ›ก Security - **API Keys:** Ensure that your OpenAI API key is kept secure. Do not commit your `.env` file or API keys to version control. Use environment variables to manage sensitive information. - **Dependencies:** Regularly update dependencies to patch any known vulnerabilities. ## ๐Ÿงช Testing SwarmJS-Node includes a testing setup using [Jest](https://jestjs.io/). To run the tests: 1. **Install Development Dependencies:** ```bash pnpm install ``` 2. **Run Tests:** ```bash pnpm run test ``` 3. **Run Tests with Coverage:** ```bash pnpm run test -- --coverage ``` ## โš™๏ธ Linting Ensure code quality and consistency by running ESLint. - **Check for Linting Errors:** ```bash pnpm run lint ``` - **Automatically Fix Linting Errors:** ```bash pnpm run lint:fix ``` ## ๐Ÿ›  Development ### ๐Ÿ”จ Building the Project Compile TypeScript source files to JavaScript: ```bash pnpm run build ``` ### ๐Ÿ“ Adding New Features 1. **Define Agent Functions:** Create new `AgentFunction` objects with appropriate `name`, `func`, and `descriptor`. 2. **Update Agents:** Initialize or update `Agent` instances with the new functions. 3. **Run and Test:** Use the example scripts or create new ones in the `examples` directory to test the new features. ### ๐Ÿงน Code Cleanup Regularly run linting and testing to maintain code quality. ```bash pnpm run lint pnpm run test ``` ## ๐Ÿค Contributing Contributions are welcome! Please follow these steps to contribute: 1. **Fork the Repository:** Click the "Fork" button at the top right of the repository page. 2. **Clone Your Fork:** ```bash git clone https://github.com/ColeMurray/swarmjs.git cd swarmjs-node ``` 3. **Create a New Branch:** ```bash git checkout -b feature/YourFeatureName ``` 4. **Make Your Changes:** Implement your feature or bug fix. 5. **Commit Your Changes:** ```bash git commit -m "Add feature: YourFeatureName" ``` 6. **Push to Your Fork:** ```bash git push origin feature/YourFeatureName ``` 7. **Create a Pull Request:** Navigate to the original repository and click "Compare & pull request." ### ๐Ÿ“œ Contribution Guidelines Please ensure that your contributions adhere to the following guidelines: - **Code Quality:** Follow the existing code style and linting rules. - **Documentation:** Update or add documentation as necessary. - **Testing:** Include tests for new features or bug fixes. - **Commit Messages:** Use clear and descriptive commit messages. For more details, refer to the [CONTRIBUTING.md](./CONTRIBUTING.md) file. ## ๐Ÿ“„ License This project is licensed under the [MIT License](./LICENSE). You are free to use, modify, and distribute this software in accordance with the license terms. ## ๐Ÿ“ซ Contact For any inquiries or support, please open an issue on the [GitHub repository](https://github.com/ColeMurray/swarmjs/issues). ## ๐ŸŒŸ Acknowledgments - [OpenAI](https://openai.com/) for providing the Swarm API. - [Lodash](https://lodash.com/) for utility functions. - [date-fns](https://date-fns.org/) for date manipulation. - [dotenv](https://github.com/motdotla/dotenv) for environment variable management. - [Jest](https://jestjs.io/) for testing framework. - [ESLint](https://eslint.org/) for linting. --- **Happy Coding! ๐Ÿš€** ## Enhanced Streaming Capabilities SwarmJS provides rich streaming capabilities with typed events to make it easier to build real-time applications: ### Stream Event Types - **RawResponsesStreamEvent**: Low-level token-by-token events from the LLM - **RunItemStreamEvent**: Higher-level events for completed items (messages, tool calls, etc.) - **AgentUpdatedStreamEvent**: Notifies when the active agent changes - **ResponseCompleteEvent**: Indicates the entire run is complete with the final response ### Streaming Example ```typescript // Import stream event types import { StreamEvent, RawResponsesStreamEvent, RunItemStreamEvent } from 'swarmjs/stream_events'; import { ItemHelpers } from 'swarmjs/items'; // Initialize and configure your agent... // Run with streaming enabled const stream = await swarm.run({ agent, messages: [{ role: 'user', content: 'Tell me a joke' }], stream: true }); // Process the stream for await (const event of stream) { switch (event.type) { case 'raw_response_event': // Handle token-by-token updates const content = event.data.choices[0]?.delta?.content || ''; process.stdout.write(content); break; case 'run_item_stream_event': if (event.name === 'message_output_created') { // Handle completed message console.log('Message complete:', ItemHelpers.extractTextContent(event.item.raw_item) ); } else if (event.name === 'tool_called') { // Handle tool call console.log('Tool called:', event.item.raw_item.function.name); } break; case 'response_complete_event': // Handle completion of the run console.log('Run complete:', event.response); break; } } ``` ## Working with Run Items RunItems represent different components of a run: - **MessageOutputItem**: Represents a message from the LLM - **ToolCallItem**: Represents a tool call from the LLM - **ToolCallOutputItem**: Represents the output of a tool call You can access these items both during streaming and in the final response: ```typescript // After a non-streaming run const response = await swarm.run({ agent, messages, stream: false }); // Access specific item types const messageItems = response.getMessageItems(); const toolCallItems = response.getToolCallItems(); const toolOutputItems = response.getToolOutputItems(); // Or access all items console.log(`Total items: ${response.items.length}`); ``` ## Advanced Usage Check out the examples directory for more advanced usage patterns: - Basic agent with tools - Multi-agent orchestration - Different streaming patterns - Tool execution and error handling