Skip to content

Latest commit

 

History

867 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PilotSwarm

Experimental — This project is under active development and not yet ready for production use. APIs may change without notice.

An open-source durable execution runtime for GitHub Copilot SDK agents. Crash recovery, durable timers, session dehydration, and multi-node scaling — powered by duroxide. Just add a connection string.

See CHANGELOG.md for release notes.

Builder Agents

If you are building layered apps on top of PilotSwarm, this repo now ships distributable builder-agent templates you can copy into your own repository:

These are not active agents in this repo. They are templates intended to be copied into a user repo under .github/agents/ and .github/skills/.

image

Quick Start

Run from source

Use Node.js 24 or later and a PostgreSQL instance you can access. Build the repository, copy the example configuration, then set DATABASE_URL and a model provider credential such as GITHUB_TOKEN in .env:

git clone https://github.com/microsoft/PilotSwarm.git
cd PilotSwarm
npm ci
npm run build
cp .env.example .env
cp .model_providers.example.json .model_providers.json
# Edit .env and .model_providers.json for your PostgreSQL and model provider.
./run.sh local --db

The local command starts the TUI with embedded workers and uses the PostgreSQL connection configured in .env. See Configuration for the available settings.

Package tarballs

PilotSwarm distributes its three npm-format packages as .tgz assets on GitHub Releases: pilotswarm-sdk, pilotswarm-horizon-store, and pilotswarm. After a release is selected, download and verify the matching tarballs using the package installation guide. Public downloads do not require repository membership. With GitHub CLI:

gh release download vX.Y.Z --repo microsoft/PilotSwarm --pattern '*.tgz' --pattern SHA256SUMS --dir dist-tarballs
(cd dist-tarballs && shasum -a 256 -c SHA256SUMS)
npm install -g ./dist-tarballs/pilotswarm-sdk-X.Y.Z.tgz \
  ./dist-tarballs/pilotswarm-horizon-store-X.Y.Z.tgz \
  ./dist-tarballs/pilotswarm-X.Y.Z.tgz

The tarballs provide the three PilotSwarm packages; npm still resolves their other dependencies through your configured registry. Keep the release's LICENSE copyright and permission notice with redistributed copies.

Use as a library in your own app

Install the SDK tarball from a GitHub Release or use a checkout, then:

import { PilotSwarmClient, PilotSwarmWorker, defineTool } from "pilotswarm-sdk";

const getWeather = defineTool("get_weather", {
    description: "Get weather for a city",
    parameters: {
        type: "object",
        properties: { city: { type: "string" } },
        required: ["city"],
    },
    handler: async ({ city }) => {
        const res = await fetch(`https://wttr.in/${city}?format=j1`);
        return await res.json();
    },
});

// Worker runs LLM turns + tools. In production it lives in its own
// long-running process (see "Durability" below); here we co-locate for demo.
const worker = new PilotSwarmWorker({ store: process.env.DATABASE_URL });
worker.registerTools([getWeather]);
await worker.start();

// Direct { store } client only because this single-process demo co-locates
// worker and client. Apps talking to a real deployment use web mode
// ({ apiUrl }) — see "Connect to a shared deployment" below.
const client = new PilotSwarmClient({ store: process.env.DATABASE_URL });
await client.start();

const session = await client.createSession({
    toolNames: ["get_weather"],
    systemMessage: "You are a weather assistant.",
});
const response = await session.sendAndWait("What's the weather in NYC?");
console.log(response);

await client.stop();
await worker.stop();

A worker-registered tool can keep durable state per session without touching SDK internals. Its handler receives invocation.facts, bound to the calling session; the model never sees it, and nothing under the tools/ key prefix is readable, writable, or searchable by any agent through the fact tools:

const proxy = defineTool("call_service", {
    description: "Call the external service for this session",
    parameters: { type: "object", properties: { query: { type: "string" } }, required: ["query"] },
    handler: async ({ query }, ctx) => {
        // Exact read, this session only. `{ scope: "root" }` binds to the spawn
        // tree's root session; `{ scope: "shared" }` is cluster-wide.
        let binding = await ctx.facts?.read("tools/my-service/binding");
        if (!binding) {
            binding = await openExternalSession(ctx.durableSessionId);
            await ctx.facts?.store("tools/my-service/binding", binding);
            binding = await ctx.facts?.read("tools/my-service/binding"); // adopt the winner if two replicas raced
        }
        return callService(binding, query);
    },
});

Reserve more prefixes for tools with new PilotSwarmWorker({ reservedFactPrefixes: ["bindings/"] }). Design: docs/proposals/tool-context-facts-accessor.md.

PilotSwarm's own framework prompt and management plugins ship embedded inside pilotswarm-sdk. Apps layer their own plugin/ directories on top; they do not need to copy the framework's built-in plugin text into their own repos.

Connect to a shared deployment

Already have a PilotSwarm deployment (see Deploying to AKS)? The portal hosts a versioned Web API (HTTP /api/v1 + WebSocket /api/v1/ws), so clients need the portal URL.

From a built checkout, attach the TUI with:

node packages/app/tui/bin/tui.js remote --api-url https://portal.example.com

Logs stream over the API. If the deployment uses Entra authentication, the TUI opens a browser for interactive sign-in. The auth login|status|logout subcommands on the same entry point manage that sign-in; use --device-code for headless hosts.

Or connect from your own app with the SDK's web mode:

const client = new PilotSwarmClient({ apiUrl: "https://portal.example.com" });
await client.start();
// Session handles work exactly as in the demo above: send, sendAndWait, on, ...

PilotSwarmManagementClient({ apiUrl }) works the same way. The zero-dependency pilotswarm-sdk/api subpath speaks the same contract — see the Web API Reference. Direct { store } client construction remains available for worker/portal embedding and internal testing only; workers always use { store }.

Durability — recurring and long-waiting agents

The single-process demo above doesn't show the durability story because the process exits as soon as the response lands. To run an agent that pauses for hours or runs a recurring schedule, the worker has to be a long-running process — typically:

  • one or more PilotSwarmWorkers in their own service (locally with npm run worker, in production on Kubernetes), and
  • clients (CLI, TUI, browser portal, or your app) connecting through the portal's Web API

The agent then calls wait(...) for one-shot delays, or cron(...) for recurring schedules. Long waits dehydrate the session to blob storage; any worker rehydrates it when the timer fires. See Architecture and Building SDK Apps for the full pattern.

What You Get

Feature Copilot SDK PilotSwarm
Tool calling ✅ ✅ Same defineTool() API
Wait/pause ❌ Blocks process ✅ Durable timer — process shuts down, resumes later
Crash recovery ❌ Session lost ✅ Automatic resume from last state
Multi-node ❌ Single process ✅ Sessions migrate between worker pods
Session persistence ❌ In-memory ✅ PostgreSQL + Azure Blob Storage
Event streaming ❌ Local only ✅ Cross-process event subscriptions

How It Works

The runtime automatically injects wait and cron tools into every session. When the LLM needs to pause or schedule recurring work:

  1. Short waits (< 30s) — sleep in-process
  2. Long waits (≥ 30s) — dehydrate session to blob storage → durable timer → any worker hydrates and continues
  3. Recurring schedules — use cron(...) so the orchestration re-arms itself automatically after each cycle
Client                        PostgreSQL                     Worker Pods
  │                              │                              │
  │── send("monitor hourly") ──→ │                              │
  │                              │── orchestration queued ────→ │
  │                              │                              │── runTurn (LLM)
  │                              │                              │── wait(3600)
  │                              │                              │── dehydrate → blob
  │                              │── durable timer (1 hour) ──→ │
  │                              │                              │── hydrate ← blob
  │                              │                              │── runTurn (LLM)
  │                              │                              │── response
  │←── result ──────────────────│                              │

Examples

Example Description Command
Chat Interactive console chat npm run chat
TUI Multi-session terminal UI with logs npm run tui
Worker Headless worker for K8s npm run worker
Tests Automated test suite npm test

Documentation

Start with the documentation hub:

Common entry points:

  • User Guide — scenario-based walkthroughs of the TUI and browser portal, simple to advanced
  • Working On PilotSwarm — contributors working on the SDK, TUI, providers, prompts, or orchestration
  • Builder Agent Templates — copyable Copilot custom agents for users building apps on top of PilotSwarm
  • Building Packages — author uploadable skills, tools, MCP integrations, and agent workflows; zero-agent packages are valid; written to be handed straight to a coding assistant
  • Building SDK Apps — app developers using PilotSwarmClient and PilotSwarmWorker
  • Building Agents For SDK Apps — the clearest path for authoring default.agent.md, named agents, skills, and tools
  • Building CLI Apps — plugin- and worker-module-driven apps on the shipped TUI
  • Building Agents For CLI Apps — the CLI-focused agent-authoring guide
  • Example Applications — includes the DevOps Command Center sample for layered apps
  • Web API Reference — the versioned HTTP + WebSocket API (/api/v1) behind SDK web mode, pilotswarm remote --api-url, and the browser portal
  • Configuration — environment variables, blob storage, worker/client options
  • Deploying to AKS — Kubernetes deployment, scaling, and rolling updates
  • Architecture — internal design and runtime flow

Requirements

  • Node.js >= 24
  • PostgreSQL
  • GitHub Copilot access token (worker-side only)
  • Azure Blob Storage (optional, for session dehydration across nodes)

License

PilotSwarm is licensed under the MIT license, retaining both Microsoft and original-contributor copyright notices. See the source provenance record.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit Contributor License Agreements.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages