Skip to content

azeebneuron/Chorus

Repository files navigation

     _____ _
    / ____| |
   | |    | |__   ___  _ __ _   _ ___
   | |    | '_ \ / _ \| '__| | | / __|
   | |____| | | | (_) | |  | |_| \__ \
    \_____|_| |_|\___/|_|   \__,_|___/

A model-agnostic TypeScript framework for building multi-agent systems.

Minimal API surface. Maximum type safety. Zero bloat.

Install

# Core package
pnpm add @chorus/core

# With Gemini provider
pnpm add @chorus/core @chorus/gemini

Quick Start

import { agent, defineTool } from "@chorus/core";
import { gemini } from "@chorus/gemini";

// Create a provider
const provider = gemini({
  apiKey: process.env.GEMINI_API_KEY!,
});

// Define a tool
const searchTool = defineTool({
  name: "search",
  description: "Search the web",
  parameters: {
    type: "object",
    properties: {
      query: { type: "string" },
    },
    required: ["query"],
  },
  execute: async ({ query }) => {
    // Your search logic
    return { results: [] };
  },
});

// Create an agent
const researcher = agent()
  .name("researcher")
  .systemPrompt("You are a research assistant.")
  .provider(provider)
  .tools([searchTool])
  .build();

// Run it
const result = await researcher.run("Find recent papers on multi-agent systems");
console.log(result.response);

Core Concepts

Agent - An entity with a role, tools, and an LLM brain.

Provider - The LLM backend. Gemini, OpenAI, Anthropic, local models - your choice.

Tool - A function the agent can call. JSON Schema parameters, typed execution.

Hooks - Lifecycle events. onBeforeGenerate, onAfterToolCall, etc.

Using Hooks

Monitor and react to agent lifecycle events:

const myAgent = agent()
  .name("monitored-agent")
  .systemPrompt("You are helpful.")
  .provider(provider)
  .onBeforeGenerate((ctx) => {
    console.log(`Starting iteration ${ctx.state.iteration}`);
  })
  .onAfterGenerate((ctx, message) => {
    console.log(`Generated: ${message.content?.slice(0, 50)}...`);
  })
  .onBeforeToolCall((ctx, name, args) => {
    console.log(`Calling ${name} with`, args);
  })
  .onAfterToolCall((ctx, name, result) => {
    console.log(`${name} returned:`, result);
  })
  .onError((ctx, error) => {
    console.error(`Error: ${error.message}`);
  })
  .build();

Custom Providers

Implement the Provider interface for any LLM:

import type { Provider } from "@chorus/core";

const myProvider: Provider = {
  name: "my-llm",
  generate: async (config) => {
    // config.messages - conversation history
    // config.tools - available tools
    // config.temperature, config.maxTokens, etc.

    const response = await callYourLLM(config);

    return {
      message: { role: "assistant", content: response.text },
      usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
      finishReason: "stop",
    };
  },
};

Packages

Package Description
@chorus/core Core primitives - agents, tools, providers
@chorus/gemini Google Gemini provider

Examples

See the examples directory:

  • simple-agent.ts - Basic agent setup
  • agent-with-tools.ts - Using tools (weather, calculator)
  • agent-with-hooks.ts - Lifecycle hooks for observability

Run examples:

cd examples
pnpm install
GEMINI_API_KEY=your-key pnpm run simple

License

MIT


Built by Rahul and Claude

About

A TypeScript framework for building multi-agent systems. Chorus is model-agnostic with dead simple API and full type inference. Simple enough to learn in minutes, powerful enough to orchestrate thousands of agents

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors